xref: /haiku/src/kits/bluetooth/LocalDevice.cpp (revision 0562493379cd52eb7103531f895f10bb8e77c085)
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/LocalDevice.h>
13 #include <bluetooth/RemoteDevice.h>
14 #include <bluetooth/DeviceClass.h>
15 #include <bluetooth/DiscoveryAgent.h>
16 
17 #include <bluetooth/bdaddrUtils.h>
18 #include <bluetoothserver_p.h>
19 #include <CommandManager.h>
20 
21 #include "KitSupport.h"
22 
23 
24 namespace Bluetooth {
25 
26 
27 LocalDevice*
28 LocalDevice::RequestLocalDeviceID(BMessage* request)
29 {
30 	BMessage reply;
31 	hci_id hid;
32 	LocalDevice* lDevice = NULL;
33 
34 	BMessenger* messenger = _RetrieveBluetoothMessenger();
35 
36 	if (messenger == NULL)
37 		return NULL;
38 
39 	if (messenger->SendMessage(request, &reply) == B_OK &&
40 		reply.FindInt32("hci_id", &hid) == B_OK ) {
41 
42 	    if (hid >= 0)
43 		    lDevice = new LocalDevice(hid);
44     }
45 
46 	delete messenger;
47     return lDevice;
48 }
49 
50 
51 #if 0
52 #pragma -
53 #endif
54 
55 
56 LocalDevice*
57 LocalDevice::GetLocalDevice()
58 {
59 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
60 
61 	return RequestLocalDeviceID(&request);
62 }
63 
64 
65 LocalDevice*
66 LocalDevice::GetLocalDevice(const hci_id hid)
67 {
68 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
69 	request.AddInt32("hci_id", hid);
70 
71 	return RequestLocalDeviceID(&request);
72 }
73 
74 
75 LocalDevice*
76 LocalDevice::GetLocalDevice(const bdaddr_t bdaddr)
77 {
78 
79 	BMessage request(BT_MSG_ACQUIRE_LOCAL_DEVICE);
80 	request.AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
81 
82 	return RequestLocalDeviceID(&request);
83 }
84 
85 
86 uint32
87 LocalDevice::GetLocalDeviceCount()
88 {
89 	BMessenger* messenger = _RetrieveBluetoothMessenger();
90 	uint32 count = 0;
91 
92 	if (messenger != NULL) {
93 
94 		BMessage request(BT_MSG_COUNT_LOCAL_DEVICES);
95 		BMessage reply;
96 
97 		if (messenger->SendMessage(&request, &reply) == B_OK)
98 			count = reply.FindInt32("count");
99 
100 		delete messenger;
101 	}
102 
103 	return count;
104 
105 }
106 
107 
108 DiscoveryAgent*
109 LocalDevice::GetDiscoveryAgent()
110 {
111 	/* TODO: Study a singleton here */
112 	return new DiscoveryAgent(this);
113 }
114 
115 
116 BString
117 LocalDevice::GetProperty(const char* property)
118 {
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", hid);
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 
169 	request.AddInt32("hci_id", hid);
170 
171 
172 	void* command = buildWriteScan(mode, &size);
173 
174 	if (command == NULL) {
175 		return B_NO_MEMORY;
176 	}
177 
178 	request.AddData("raw command", B_ANY_TYPE, command, size);
179 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
180 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, 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 	/* ADD ID */
212 	request.AddInt32("hci_id", hid);
213 	request.AddData("raw command", B_ANY_TYPE, command, size);
214 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
215 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
216 
217 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
218 		if (reply.FindData("bdaddr", B_ANY_TYPE, 0, (const void**)&bdaddr, &ssize) == B_OK )
219 			return *bdaddr;
220 	}
221 
222 	return bdaddrUtils::LocalAddress();
223 }
224 
225 
226 BString
227 LocalDevice::GetFriendlyName()
228 {
229 	if (fMessenger == NULL)
230 		return BString("Unknown|Messenger");
231 
232 	size_t	size;
233 	void* command = buildReadLocalName(&size);
234 	if (command == NULL)
235 		return BString("Unknown|NoMemory");
236 
237 	BString friendlyname;
238 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
239 	BMessage reply;
240 
241 
242 	request.AddInt32("hci_id", hid);
243 	request.AddData("raw command", B_ANY_TYPE, command, size);
244 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
245 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
246 
247 	if (fMessenger->SendMessage(&request, &reply) == B_OK &&
248 		reply.FindString("friendlyname", &friendlyname) == B_OK){
249 
250 		return friendlyname;
251 	}
252 
253 	return BString("Unknown|ServerFailed");
254 }
255 
256 
257 DeviceClass
258 LocalDevice::GetDeviceClass()
259 {
260 
261 	if (fDeviceClass.IsUnknownDeviceClass()) {
262 
263 		if (fMessenger == NULL)
264 			return fDeviceClass;
265 
266 		size_t	size;
267 		void* command = buildReadClassOfDevice(&size);
268 		if (command == NULL)
269 			return fDeviceClass;
270 
271 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
272 		BMessage reply;
273 		const uint8*	record;
274 		ssize_t	ssize;
275 
276 		request.AddInt32("hci_id", hid);
277 		request.AddData("raw command", B_ANY_TYPE, command, size);
278 	    request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
279 	    request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV));
280 
281 		if (fMessenger->SendMessage(&request, &reply) == B_OK &&
282 			reply.FindData("devclass", B_ANY_TYPE, 0, (const void**)&record, &ssize) == B_OK) {
283 
284 			fDeviceClass.SetRecord(*record);
285 		}
286 	}
287 
288 	return fDeviceClass;
289 
290 }
291 
292 
293 status_t
294 LocalDevice::ReadLocalVersion()
295 {
296 	int8	 bt_status = BT_ERROR;
297 
298 	BluetoothCommand<> localVersion(OGF_INFORMATIONAL_PARAM,OCF_READ_LOCAL_VERSION);
299 
300 
301 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
302 	BMessage reply;
303 
304 	request.AddInt32("hci_id", hid);
305 	request.AddData("raw command", B_ANY_TYPE, localVersion.Data(), localVersion.Size());
306 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
307 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION));
308 
309 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
310 		reply.FindInt8("status", &bt_status);
311 
312 	return bt_status;
313 }
314 
315 
316 status_t
317 LocalDevice::ReadBufferSize()
318 {
319 	int8	 bt_status = BT_ERROR;
320 
321 	BluetoothCommand<> BufferSize(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE);
322 
323 
324 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
325 	BMessage reply;
326 
327 	request.AddInt32("hci_id", hid);
328 	request.AddData("raw command", B_ANY_TYPE, BufferSize.Data(), BufferSize.Size());
329 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
330 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE));
331 
332 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
333 		reply.FindInt8("status", &bt_status);
334 
335 	return bt_status;
336 }
337 
338 
339 status_t
340 LocalDevice::Reset()
341 {
342 	int8	 bt_status = BT_ERROR;
343 
344 	BluetoothCommand<> Reset(OGF_CONTROL_BASEBAND, OCF_RESET);
345 
346 
347 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
348 	BMessage reply;
349 
350 	request.AddInt32("hci_id", hid);
351 	request.AddData("raw command", B_ANY_TYPE, Reset.Data(), Reset.Size());
352 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
353 	request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET));
354 
355 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
356 		reply.FindInt8("status", &bt_status);
357 
358 	return bt_status;
359 
360 }
361 
362 /*
363 ServiceRecord
364 LocalDevice::getRecord(Connection notifier) {
365 
366 }
367 
368 void
369 LocalDevice::updateRecord(ServiceRecord srvRecord) {
370 
371 }
372 */
373 
374 
375 LocalDevice::LocalDevice(hci_id hid) : hid(hid)
376 {
377 	fMessenger = _RetrieveBluetoothMessenger();
378 	ReadLocalVersion();
379 	uint32 value;
380 
381 	// HARDCODE -> move this to addons
382 	if (GetProperty("manufacturer", &value) == B_OK
383 		&& value == 15) {
384 
385 		// Uncomment this out if your Broadcom dongle is not working properly
386 		// Reset();	// Perform a reset to Broadcom buggyland
387 
388 
389 //#define BT_WRITE_BDADDR_FOR_BCM2035
390 #ifdef BT_WRITE_BDADDR_FOR_BCM2035
391 		// try the bcm stuff
392 		int8	 bt_status = BT_ERROR;
393 
394 		BluetoothCommand<typed_command(hci_write_bcm2035_bdaddr)> writeAddress(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR);
395 
396 		BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
397 		BMessage reply;
398 		writeAddress->bdaddr.b[0] = 0x3C;
399 		writeAddress->bdaddr.b[1] = 0x19;
400 		writeAddress->bdaddr.b[2] = 0x30;
401 		writeAddress->bdaddr.b[3] = 0xC9;
402 		writeAddress->bdaddr.b[4] = 0x03;
403 		writeAddress->bdaddr.b[5] = 0x00;
404 
405 		request.AddInt32("hci_id", hid);
406 		request.AddData("raw command", B_ANY_TYPE, writeAddress.Data(), writeAddress.Size());
407 		request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
408 		request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR));
409 
410 		if (fMessenger->SendMessage(&request, &reply) == B_OK)
411 			reply.FindInt8("status", &bt_status);
412 #endif
413 	}
414 
415 	ReadBufferSize();
416 }
417 
418 
419 LocalDevice::~LocalDevice()
420 {
421 	if (fMessenger)
422 		delete fMessenger;
423 }
424 
425 
426 }
427