xref: /haiku/src/kits/bluetooth/LocalDevice.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
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 
81 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
82 	request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
83 
84 	return RequestLocalDeviceID(&request);
85 }
86 
87 
88 uint32
89 LocalDevice::GetLocalDeviceCount()
90 {
91 	BMessenger* messenger = _RetrieveBluetoothMessenger();
92 	uint32 count = 0;
93 
94 	if (messenger != NULL) {
95 
96 		BMessage request(BT_MSG_COUNT_LOCAL_DEVICES);
97 		BMessage reply;
98 
99 		if (messenger->SendMessage(&request, &reply) == B_OK)
100 			count = reply.FindInt32("count");
101 
102 		delete messenger;
103 	}
104 
105 	return count;
106 
107 }
108 
109 
110 DiscoveryAgent*
111 LocalDevice::GetDiscoveryAgent()
112 {
113 	/* TODO: Study a singleton here */
114 	return new (std::nothrow)DiscoveryAgent(this);
115 }
116 
117 
118 BString
119 LocalDevice::GetProperty(const char* property)
120 {
121 
122 	return NULL;
123 
124 }
125 
126 
127 status_t
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
151 LocalDevice::GetDiscoverable()
152 {
153 
154 	return 0;
155 }
156 
157 
158 status_t
159 LocalDevice::SetDiscoverable(int mode)
160 {
161 	if (fMessenger == NULL)
162 		return B_ERROR;
163 
164 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
165 	BMessage reply;
166 
167 	size_t size;
168 	int8 bt_status = BT_ERROR;
169 
170 	request.AddInt32("hci_id", fHid);
171 
172 
173 	void* command = buildWriteScan(mode, &size);
174 
175 	if (command == NULL) {
176 		return B_NO_MEMORY;
177 	}
178 
179 	request.AddData("raw command", B_ANY_TYPE, command, size);
180 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
181 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
182 		OCF_WRITE_SCAN_ENABLE));
183 
184 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
185 		if (reply.FindInt8("status", &bt_status ) == B_OK ) {
186 			return bt_status;
187 
188 		}
189 
190 	}
191 
192 	return B_ERROR;
193 }
194 
195 
196 bdaddr_t
197 LocalDevice::GetBluetoothAddress()
198 {
199 	if (fMessenger == NULL)
200 		return bdaddrUtils::LocalAddress();
201 
202 	size_t	size;
203 	void* command = buildReadBdAddr(&size);
204 
205 	if (command == NULL)
206 		return bdaddrUtils::LocalAddress();
207 
208 	const bdaddr_t* bdaddr;
209 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
210 	BMessage reply;
211 	ssize_t	ssize;
212 
213 	request.AddInt32("hci_id", fHid);
214 	request.AddData("raw command", B_ANY_TYPE, command, size);
215 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
216 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
217 		OCF_READ_BD_ADDR));
218 
219 	if (fMessenger->SendMessage(&request, &reply) == B_OK
220 		&& reply.FindData("bdaddr", B_ANY_TYPE, 0,
221 			(const void**)&bdaddr, &ssize) == B_OK)
222 			return *bdaddr;
223 
224 	return bdaddrUtils::LocalAddress();
225 }
226 
227 
228 hci_id
229 LocalDevice::ID(void) const
230 {
231 	return fHid;
232 }
233 
234 
235 BString
236 LocalDevice::GetFriendlyName()
237 {
238 	if (fMessenger == NULL)
239 		return BString("Unknown|Messenger");
240 
241 	size_t	size;
242 	void* command = buildReadLocalName(&size);
243 	if (command == NULL)
244 		return BString("Unknown|NoMemory");
245 
246 	BString friendlyname;
247 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
248 	BMessage reply;
249 
250 
251 	request.AddInt32("hci_id", fHid);
252 	request.AddData("raw command", B_ANY_TYPE, command, size);
253 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
254 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
255 		OCF_READ_LOCAL_NAME));
256 
257 	if (fMessenger->SendMessage(&request, &reply) == B_OK
258 		&& reply.FindString("friendlyname", &friendlyname) == B_OK)
259 		return friendlyname;
260 
261 	return BString("Unknown|ServerFailed");
262 }
263 
264 
265 DeviceClass
266 LocalDevice::GetDeviceClass()
267 {
268 
269 //	if (fDeviceClass.IsUnknownDeviceClass()) {
270 
271 		if (fMessenger == NULL)
272 			return fDeviceClass;
273 
274 		size_t	size;
275 		void* command = buildReadClassOfDevice(&size);
276 		if (command == NULL)
277 			return fDeviceClass;
278 
279 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
280 		BMessage reply;
281 		const uint8* bufferRecord;
282 		ssize_t	ssize;
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_CLASS_OF_DEV));
289 
290 		if (fMessenger->SendMessage(&request, &reply) == B_OK
291 			&& reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&bufferRecord,
292 			&ssize) == B_OK) {
293 			uint8 record[3] = { bufferRecord[0], bufferRecord[1], bufferRecord[2] };
294 			fDeviceClass.SetRecord(record);
295 		}
296 //	}
297 
298 	return fDeviceClass;
299 
300 }
301 
302 
303 status_t
304 LocalDevice::SetDeviceClass(DeviceClass deviceClass)
305 {
306 	int8 bt_status = BT_ERROR;
307 
308 	if (fMessenger == NULL)
309 		return bt_status;
310 
311 	BluetoothCommand<typed_command(hci_write_dev_class)>
312 		setDeviceClass(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV);
313 
314 	setDeviceClass->dev_class[0] = deviceClass.Record() & 0xFF;
315 	setDeviceClass->dev_class[1] = (deviceClass.Record() & 0xFF00) >> 8;
316 	setDeviceClass->dev_class[2] = (deviceClass.Record() & 0xFF0000) >> 16;
317 
318 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
319 	BMessage reply;
320 
321 	request.AddInt32("hci_id", fHid);
322 	request.AddData("raw command", B_ANY_TYPE,
323 		setDeviceClass.Data(), setDeviceClass.Size());
324 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
325 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
326 		OCF_WRITE_CLASS_OF_DEV));
327 
328 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
329 		reply.FindInt8("status", &bt_status);
330 
331 	return bt_status;
332 
333 }
334 
335 
336 status_t
337 LocalDevice::ReadLocalVersion()
338 {
339 	int8 bt_status = BT_ERROR;
340 
341 	BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,
342 		OCF_READ_LOCAL_VERSION);
343 
344 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
345 	BMessage reply;
346 
347 	request.AddInt32("hci_id", fHid);
348 	request.AddData("raw command", B_ANY_TYPE,
349 		localVersion.Data(), localVersion.Size());
350 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
351 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
352 		OCF_READ_LOCAL_VERSION));
353 
354 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
355 		reply.FindInt8("status", &bt_status);
356 
357 	return bt_status;
358 }
359 
360 
361 status_t
362 LocalDevice::ReadBufferSize()
363 {
364 	int8 bt_status = BT_ERROR;
365 
366 	BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE);
367 
368 
369 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
370 	BMessage reply;
371 
372 	request.AddInt32("hci_id", fHid);
373 	request.AddData("raw command", B_ANY_TYPE,
374 		BufferSize.Data(), BufferSize.Size());
375 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
376 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM,
377 		OCF_READ_BUFFER_SIZE));
378 
379 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
380 		reply.FindInt8("status", &bt_status);
381 
382 	return bt_status;
383 }
384 
385 
386 status_t
387 LocalDevice::Reset()
388 {
389 	int8 bt_status = BT_ERROR;
390 
391 	BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
392 
393 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
394 	BMessage reply;
395 
396 	request.AddInt32("hci_id", fHid);
397 	request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size());
398 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
399 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND,
400 		OCF_RESET));
401 
402 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
403 		reply.FindInt8("status", &bt_status);
404 
405 	return bt_status;
406 
407 }
408 
409 /*
410 ServiceRecord
411 LocalDevice::getRecord(Connection notifier) {
412 
413 }
414 
415 void
416 LocalDevice::updateRecord(ServiceRecord srvRecord) {
417 
418 }
419 */
420 
421 
422 LocalDevice::LocalDevice(hci_id hid) : fHid(hid)
423 {
424 	fMessenger = _RetrieveBluetoothMessenger();
425 	ReadLocalVersion();
426 	uint32 value;
427 
428 	// HARDCODE -> move this to addons
429 	if (GetProperty("manufacturer", &value) == B_OK
430 		&& value == 15) {
431 
432 		// Uncomment this out if your Broadcom dongle is not working properly
433 		// Reset();	// Perform a reset to Broadcom buggyland
434 
435 // Uncomment this out if your Broadcom dongle has a null bdaddr
436 //#define BT_WRITE_BDADDR_FOR_BCM2035
437 #ifdef BT_WRITE_BDADDR_FOR_BCM2035
438 #warning Writting broadcom bdaddr @ init.
439 		// try write bdaddr to a bcm2035 -> will be moved to an addon
440 		int8 bt_status = BT_ERROR;
441 
442 		BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)>
443 			writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR);
444 
445 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
446 		BMessage reply;
447 		writeAddress->bdaddr.b[0] = 0x3C;
448 		writeAddress->bdaddr.b[1] = 0x19;
449 		writeAddress->bdaddr.b[2] = 0x30;
450 		writeAddress->bdaddr.b[3] = 0xC9;
451 		writeAddress->bdaddr.b[4] = 0x03;
452 		writeAddress->bdaddr.b[5] = 0x00;
453 
454 		request.AddInt32("hci_id", fHid);
455 		request.AddData("raw command", B_ANY_TYPE,
456 			writeAddress.Data(), writeAddress.Size());
457 		request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
458 		request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD,
459 			OCF_WRITE_BCM2035_BDADDR));
460 
461 		if (fMessenger->SendMessage(&request, &reply) == B_OK)
462 			reply.FindInt8("status", &bt_status);
463 #endif
464 	}
465 
466 	ReadBufferSize();
467 }
468 
469 
470 LocalDevice::~LocalDevice()
471 {
472 	delete fMessenger;
473 }
474 
475 
476 }
477