xref: /haiku/src/kits/bluetooth/CommandManager.cpp (revision 776c58b2b56d8bcf33638a2ecb6c697f95a1cbf3)
1 /*
2  * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  * Copyright 2008 Mika Lindqvist
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 
7 #include "CommandManager.h"
8 
9 
10 #include <bluetooth/bluetooth_error.h>
11 
12 inline void* buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize,
13 	size_t* outsize)
14 {
15 	struct hci_command_header* header;
16 
17 #ifdef BT_IOCTLS_PASS_SIZE
18 	header = (struct hci_command_header*) malloc(psize
19 		+ sizeof(struct hci_command_header));
20 	*outsize = psize + sizeof(struct hci_command_header);
21 #else
22 	size_t* size = (size_t*)malloc(psize + sizeof(struct hci_command_header)
23 		+ sizeof(size_t));
24 	*outsize = psize + sizeof(struct hci_command_header) + sizeof(size_t);
25 
26 	*size = psize + sizeof(struct hci_command_header);
27 	header = (struct hci_command_header*) (((uint8*)size)+4);
28 #endif
29 
30 
31 	if (header != NULL) {
32 
33 		header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf));
34 		header->clen = psize;
35 
36 		if (param != NULL && psize != 0) {
37 			*param = ((uint8*)header) + sizeof(struct hci_command_header);
38 		}
39 	}
40 #ifdef BT_IOCTLS_PASS_SIZE
41 	return header;
42 #else
43 	return (void*)size;
44 #endif
45 }
46 
47 
48 // This is for request that only require a Command complete in reply.
49 
50 // Propagate to ReadBufferSize => reply stored in server side
51 // ReadLocalVersion => reply stored in server side
52 // Reset => no reply
53 
54 // Request that do not need any input parameter
55 // Output reply can be fit in 32 bits field without talking status into account
56 status_t
57 NonParameterCommandRequest(uint8 ofg, uint8 ocf, int32* result, hci_id hId,
58 	BMessenger* messenger)
59 {
60 	int8 bt_status = BT_ERROR;
61 
62 	BluetoothCommand<> simpleCommand(ofg, ocf);
63 
64 	BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
65 	BMessage reply;
66 
67 	request.AddInt32("hci_id", hId);
68 	request.AddData("raw command", B_ANY_TYPE,
69 		simpleCommand.Data(), simpleCommand.Size());
70 	request.AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
71 	request.AddInt16("opcodeExpected", PACK_OPCODE(ofg, ocf));
72 
73 	if (messenger->SendMessage(&request, &reply) == B_OK) {
74 		reply.FindInt8("status", &bt_status);
75 		if (result != NULL)
76 			reply.FindInt32("result", result);
77 	}
78 
79 	return bt_status;
80 }
81 
82 
83 #if 0
84 #pragma mark - CONTROL BASEBAND -
85 #endif
86 
87 
88 void* buildReset(size_t* outsize)
89 {
90 	return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET,
91 		NULL, 0, outsize);
92 }
93 
94 
95 void* buildReadLocalName(size_t* outsize)
96 {
97 	return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME,
98 		NULL, 0, outsize);
99 }
100 
101 
102 void* buildReadClassOfDevice(size_t* outsize)
103 {
104 	return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV,
105 	NULL, 0, outsize);
106 }
107 
108 
109 void* buildReadScan(size_t* outsize)
110 {
111 	return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_SCAN_ENABLE,
112 	NULL, 0, outsize);
113 }
114 
115 
116 void* buildWriteScan(uint8 scanmode, size_t* outsize)
117 {
118 	struct hci_write_scan_enable* param;
119 	void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE,
120 		(void**) &param, sizeof(struct hci_write_scan_enable), outsize);
121 
122 
123 	if (command != NULL) {
124 		param->scan = scanmode;
125 	}
126 
127 	return command;
128 }
129 
130 
131 #if 0
132 #pragma mark - LINK CONTROL -
133 #endif
134 
135 
136 void* buildRemoteNameRequest(bdaddr_t bdaddr, uint8 pscan_rep_mode,
137 	uint16 clock_offset, size_t* outsize)
138 {
139 
140 	struct hci_remote_name_request* param;
141 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST,
142 		(void**)&param, sizeof(struct hci_remote_name_request), outsize);
143 
144 	if (command != NULL) {
145 		param->bdaddr = bdaddr;
146 		param->pscan_rep_mode = pscan_rep_mode;
147 		param->clock_offset = clock_offset;
148 	}
149 
150 	return command;
151 }
152 
153 
154 void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize)
155 {
156 
157 	struct hci_cp_inquiry* param;
158 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY,
159 		(void**) &param, sizeof(struct hci_cp_inquiry), outsize);
160 
161 	if (command != NULL) {
162 
163 		param->lap[2] = (lap >> 16) & 0xFF;
164 		param->lap[1] = (lap >>  8) & 0xFF;
165 		param->lap[0] = (lap >>  0) & 0xFF;
166 		param->length = length;
167 		param->num_rsp = num_rsp;
168 	}
169 
170 	return command;
171 }
172 
173 
174 void* buildInquiryCancel(size_t* outsize)
175 {
176 
177 	return buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL, NULL, 0, outsize);
178 
179 }
180 
181 
182 void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16],
183 	size_t* outsize)
184 {
185 	struct hci_cp_pin_code_reply* param;
186 
187 	if (length > HCI_PIN_SIZE)  // PinCode cannot be longer than 16
188 		return NULL;
189 
190 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY,
191 		(void**)&param, sizeof(struct hci_cp_pin_code_reply), outsize);
192 
193 	if (command != NULL) {
194 		param->bdaddr = bdaddr;
195 		param->pin_len = length;
196 		memcpy(&param->pin_code, pincode, length);
197 	}
198 
199 	return command;
200 }
201 
202 
203 void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize)
204 {
205 
206 	struct hci_cp_pin_code_neg_reply* param;
207 
208 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY,
209 		(void**) &param, sizeof(struct hci_cp_pin_code_neg_reply), outsize);
210 
211 	if (command != NULL) {
212 
213 		param->bdaddr = bdaddr;
214 
215 	}
216 
217 	return command;
218 }
219 
220 
221 void* buildAcceptConnectionRequest(bdaddr_t bdaddr, uint8 role, size_t* outsize)
222 {
223 	struct hci_cp_accept_conn_req* param;
224 
225 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ,
226 					(void**) &param, sizeof(struct hci_cp_accept_conn_req), outsize);
227 
228 	if (command != NULL) {
229 		param->bdaddr = bdaddr;
230 		param->role = role;
231 	}
232 
233 	return command;
234 }
235 
236 
237 void* buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize)
238 {
239 	struct hci_cp_reject_conn_req* param;
240 
241 	void* command = buildCommand(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ,
242 					(void**)&param, sizeof(struct hci_cp_reject_conn_req),
243 					outsize);
244 
245 	if (command != NULL) {
246 		param->bdaddr = bdaddr;
247 	}
248 
249 	return command;
250 }
251 
252 
253 #if 0
254 #pragma mark - INFORMATIONAL_PARAM -
255 #endif
256 
257 void* buildReadLocalVersionInformation(size_t* outsize)
258 {
259 	return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION,
260 		NULL, 0, outsize);
261 }
262 
263 
264 void* buildReadBufferSize(size_t* outsize)
265 {
266 	return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE,
267 		NULL, 0, outsize);
268 }
269 
270 
271 void* buildReadBdAddr(size_t* outsize)
272 {
273 	return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR,
274 		NULL, 0, outsize);
275 }
276 
277 
278 const char* bluetoothManufacturers[] = {
279 	"Ericsson Technology Licensing",
280 	"Nokia Mobile Phones",
281 	"Intel Corp.",
282 	"IBM Corp.",
283 	"Toshiba Corp.",
284 	"3Com",
285 	"Microsoft",
286 	"Lucent",
287 	"Motorola",
288 	"Infineon Technologies AG",
289 	"Cambridge Silicon Radio",
290 	"Silicon Wave",
291 	"Digianswer A/S",
292 	"Texas Instruments Inc.",
293 	"Parthus Technologies Inc.",
294 	"Broadcom Corporation",
295 	"Mitel Semiconductor",
296 	"Widcomm, Inc.",
297 	"Zeevo, Inc.",
298 	"Atmel Corporation",
299 	"Mitsubishi Electric Corporation",
300 	"RTX Telecom A/S",
301 	"KC Technology Inc.",
302 	"Newlogic",
303 	"Transilica, Inc.",
304 	"Rohde & Schwartz GmbH & Co. KG",
305 	"TTPCom Limited",
306 	"Signia Technologies, Inc.",
307 	"Conexant Systems Inc.",
308 	"Qualcomm",
309 	"Inventel",
310 	"AVM Berlin",
311 	"BandSpeed, Inc.",
312 	"Mansella Ltd",
313 	"NEC Corporation",
314 	"WavePlus Technology Co., Ltd.",
315 	"Alcatel",
316 	"Philips Semiconductors",
317 	"C Technologies",
318 	"Open Interface",
319 	"R F Micro Devices",
320 	"Hitachi Ltd",
321 	"Symbol Technologies, Inc.",
322 	"Tenovis",
323 	"Macronix International Co. Ltd.",
324 	"GCT Semiconductor",
325 	"Norwood Systems",
326 	"MewTel Technology Inc.",
327 	"ST Microelectronics",
328 	"Synopsys",
329 	"Red-M (Communications) Ltd",
330 	"Commil Ltd",
331 	"Computer Access Technology Corporation (CATC)",
332 	"Eclipse (HQ España) S.L.",
333 	"Renesas Technology Corp.",
334 	"Mobilian Corporation",
335 	"Terax",
336 	"Integrated System Solution Corp.",
337 	"Matsushita Electric Industrial Co., Ltd.",
338 	"Gennum Corporation",
339 	"Research In Motion",
340 	"IPextreme, Inc.",
341 	"Systems and Chips, Inc",
342 	"Bluetooth SIG, Inc",
343 	"Seiko Epson Corporation",
344 	"Integrated Silicon Solution Taiwain, Inc.",
345 	"CONWISE Technology Corporation Ltd",
346 	"PARROT SA",
347 	"Socket Communications",
348 	"Atheros Communications, Inc.",
349 	"MediaTek, Inc.",
350 	"Bluegiga",	/* (tentative) */
351 	"Marvell Technology Group Ltd.",
352 	"3DSP Corporation",
353 	"Accel Semiconductor Ltd.",
354 	"Continental Automotive Systems",
355 	"Apple, Inc.",
356 	"Staccato Communications, Inc."
357 };
358 
359 
360 const char* linkControlCommands[] = {
361 	"Inquiry",
362 	"Inquiry Cancel",
363 	"Periodic Inquiry Mode",
364 	"Exit Periodic Inquiry Mode",
365 	"Create Connection",
366 	"Disconnect",
367 	"Add SCO Connection", // not on 2.1
368 	"Cancel Create Connection",
369 	"Accept Connection Request",
370 	"Reject Connection Request",
371 	"Link Key Request Reply",
372 	"Link Key Request Negative Reply",
373 	"PIN Code Request Reply",
374 	"PIN Code Request Negative Reply",
375 	"Change Connection Packet Type",
376 	"Reserved", // not on 2.1",
377 	"Authentication Requested",
378 	"Reserved", // not on 2.1",
379 	"Set Connection Encryption",
380 	"Reserved", // not on 2.1",
381 	"Change Connection Link Key",
382 	"Reserved", // not on 2.1",
383 	"Master Link Key",
384 	"Reserved", // not on 2.1",
385 	"Remote Name Request",
386 	"Cancel Remote Name Request",
387 	"Read Remote Supported Features",
388 	"Read Remote Extended Features",
389 	"Read Remote Version Information",
390 	"Reserved", // not on 2.1",
391 	"Read Clock Offset",
392 	"Read LMP Handle",
393 	"Reserved",
394 	"Reserved",
395 	"Reserved",
396 	"Reserved",
397 	"Reserved",
398 	"Reserved",
399 	"Reserved",
400 	"Setup Synchronous Connection",
401 	"Accept Synchronous Connection",
402 	"Reject Synchronous Connection",
403 	"IO Capability Request Reply",
404 	"User Confirmation Request Reply",
405 	"User Confirmation Request Negative Reply",
406 	"User Passkey Request Reply",
407 	"User Passkey Request Negative Reply",
408 	"Remote OOB Data Request Reply",
409 	"Reserved",
410 	"Reserved",
411 	"Remote OOB Data Request Negative Reply",
412 	"IO Capabilities Response Negative Reply"
413 };
414 
415 
416 const char* linkPolicyCommands[] = {
417 	"Hold Mode",
418 	"Reserved",
419 	"Sniff Mode",
420 	"Exit Sniff Mode",
421 	"Park State",
422 	"Exit Park State",
423 	"QoS Setup",
424 	"Reserved",
425 	"Role Discovery",
426 	"Reserved",
427 	"Switch Role",
428 	"Read Link Policy Settings",
429 	"Write Link Policy Settings",
430 	"Read Default Link Policy Settings",
431 	"Write Default Link Policy Settings",
432 	"Flow Specification",
433 	"Sniff Subrating"
434 };
435 
436 
437 const char* controllerBasebandCommands[] = {
438 	"Set Event Mask",
439 	"Reserved",
440 	"Reset",
441 	"Reserved",
442 	"Set Event Filter",
443 	"Reserved",
444 	"Reserved",
445 	"Flush",
446 	"Read PIN Type",
447 	"Write PIN Type",
448 	"Create New Unit Key",
449 	"Reserved",
450 	"Read Stored Link Key",
451 	"Reserved",
452 	"Reserved",
453 	"Reserved",
454 	"Write Stored Link Key",
455 	"Delete Stored Link Key",
456 	"Write Local Name",
457 	"Read Local Name",
458 	"Read Connection Accept Timeout",
459 	"Write Connection Accept Timeout",
460 	"Read Page Timeout",
461 	"Write Page Timeout",
462 	"Read Scan Enable",
463 	"Write Scan Enable",
464 	"Read Page Scan Activity",
465 	"Write Page Scan Activity",
466 	"Read Inquiry Scan Activity",
467 	"Write Inquiry Scan Activity",
468 	"Read Authentication Enable",
469 	"Write Authentication Enable",
470 	"Read Encryption Mode", // not 2.1
471 	"Write Encryption Mode",// not 2.1
472 	"Read Class Of Device",
473 	"Write Class Of Device",
474 	"Read Voice Setting",
475 	"Write Voice Setting",
476 	"Read Automatic Flush Timeout",
477 	"Write Automatic Flush Timeout",
478 	"Read Num Broadcast Retransmissions",
479 	"Write Num Broadcast Retransmissions",
480 	"Read Hold Mode Activity",
481 	"Write Hold Mode Activity",
482 	"Read Transmit Power Level",
483 	"Read Synchronous Flow Control Enable",
484 	"Write Synchronous Flow Control Enable",
485 	"Reserved",
486 	"Set Host Controller To Host Flow Control",
487 	"Reserved",
488 	"Host Buffer Size",
489 	"Reserved",
490 	"Host Number Of Completed Packets",
491 	"Read Link Supervision Timeout",
492 	"Write Link Supervision Timeout",
493 	"Read Number of Supported IAC",
494 	"Read Current IAC LAP",
495 	"Write Current IAC LAP",
496 	"Read Page Scan Period Mode", // not 2.1
497 	"Write Page Scan Period Mode", // not 2.1
498 	"Read Page Scan Mode",		// not 2.1
499 	"Write Page Scan Mode",		// not 2.1
500 	"Set AFH Channel Classification",
501 	"Reserved",
502 	"Reserved",
503 	"Read Inquiry Scan Type",
504 	"Write Inquiry Scan Type",
505 	"Read Inquiry Mode",
506 	"Write Inquiry Mode",
507 	"Read Page Scan Type",
508 	"Write Page Scan Type",
509 	"Read AFH Channel Assessment Mode",
510 	"Write AFH Channel Assessment Mode",
511 	"Reserved",
512 	"Reserved",
513 	"Reserved",
514 	"Reserved",
515 	"Reserved",
516 	"Reserved",
517 	"Reserved",
518 	"Read Extended Inquiry Response",
519 	"Write Extended Inquiry Response",
520 	"Refresh Encryption Key",
521 	"Reserved",
522 	"Read Simple Pairing Mode",
523 	"Write Simple Pairing Mode",
524 	"Read Local OOB Data",
525 	"Read Inquiry Transmit Power Level",
526 	"Write Inquiry Transmit Power Level",
527 	"Read Default Erroneous Data Reporting",
528 	"Write Default Erroneous Data Reporting",
529 	"Reserved",
530 	"Reserved",
531 	"Reserved",
532 	"Enhanced Flush",
533 	"Send Keypress Notification"
534 };
535 
536 
537 const char* informationalParametersCommands[] = {
538 	"Read Local Version Information",
539 	"Read Local Supported Commands",
540 	"Read Local Supported Features",
541 	"Read Local Extended Features",
542 	"Read Buffer Size",
543 	"Reserved",
544 	"Read Country Code", // not 2.1
545 	"Reserved",
546 	"Read BD ADDR"
547 };
548 
549 
550 const char* statusParametersCommands[] = {
551 	"Read Failed Contact Counter",
552 	"Reset Failed Contact Counter",
553 	"Read Link Quality",
554 	"Reserved",
555 	"Read RSSI",
556 	"Read AFH Channel Map",
557 	"Read Clock",
558 };
559 
560 
561 const char* testingCommands[] = {
562 	"Read Loopback Mode",
563 	"Write Loopback Mode",
564 	"Enable Device Under Test Mode",
565 	"Write Simple Pairing Debug Mode",
566 };
567 
568 
569 const char* bluetoothEvents[] = {
570 	"Inquiry Complete",
571 	"Inquiry Result",
572 	"Conn Complete",
573 	"Conn Request",
574 	"Disconnection Complete",
575 	"Auth Complete",
576 	"Remote Name Request Complete",
577 	"Encrypt Change",
578 	"Change Conn Link Key Complete",
579 	"Master Link Key Compl",
580 	"Rmt Features",
581 	"Rmt Version",
582 	"Qos Setup Complete",
583 	"Command Complete",
584 	"Command Status",
585 	"Hardware Error",
586 	"Flush Occur",
587 	"Role Change",
588 	"Num Comp Pkts",
589 	"Mode Change",
590 	"Return Link Keys",
591 	"Pin Code Req",
592 	"Link Key Req",
593 	"Link Key Notify",
594 	"Loopback Command",
595 	"Data Buffer Overflow",
596 	"Max Slot Change",
597 	"Read Clock Offset Compl",
598 	"Con Pkt Type Changed",
599 	"Qos Violation",
600 	"Reserved",
601 	"Page Scan Rep Mode Change",
602 	"Flow Specification",
603 	"Inquiry Result With Rssi",
604 	"Remote Extended Features",
605 	"Reserved",
606 	"Reserved",
607 	"Reserved",
608 	"Reserved",
609 	"Reserved",
610 	"Reserved",
611 	"Reserved",
612 	"Reserved",
613 	"Synchronous Connection Completed",
614 	"Synchronous Connection Changed",
615 	"Reserved",
616 	"Extended Inquiry Result",
617 	"Encryption Key Refresh Complete",
618 	"Io Capability Request",
619 	"Io Capability Response",
620 	"User Confirmation Request",
621 	"User Passkey Request",
622 	"Oob Data Request",
623 	"Simple Pairing Complete",
624 	"Reserved",
625 	"Link Supervision Timeout Changed",
626 	"Enhanced Flush Complete",
627 	"Reserved",
628 	"Reserved",
629 	"Keypress Notification",
630 	"Remote Host Supported Features Notification"
631 };
632 
633 
634 const char* bluetoothErrors[] = {
635 	"No Error",
636 	"Unknown Command",
637 	"No Connection",
638 	"Hardware Failure",
639 	"Page Timeout",
640 	"Authentication Failure",
641 	"Pin Or Key Missing",
642 	"Memory Full",
643 	"Connection Timeout",
644 	"Max Number Of Connections",
645 	"Max Number Of Sco Connections",
646 	"Acl Connection Exists",
647 	"Command Disallowed",
648 	"Rejected Limited Resources",
649 	"Rejected Security",
650 	"Rejected Personal",
651 	"Host Timeout",
652 	"Unsupported Feature",
653 	"Invalid Parameters",
654 	"Remote User Ended Connection",
655 	"Remote Low Resources",
656 	"Remote Power Off",
657 	"Connection Terminated",
658 	"Repeated Attempts",
659 	"Pairing Not Allowed",
660 	"Unknown Lmp Pdu",
661 	"Unsupported Remote Feature",
662 	"Sco Offset Rejected",
663 	"Sco Interval Rejected",
664 	"Air Mode Rejected",
665 	"Invalid Lmp Parameters",
666 	"Unspecified Error",
667 	"Unsupported Lmp Parameter Value",
668 	"Role Change Not Allowed",
669 	"Lmp Response Timeout",
670 	"Lmp Error Transaction Collision",
671 	"Lmp Pdu Not Allowed",
672 	"Encryption Mode Not Accepted",
673 	"Unit Link Key Used",
674 	"Qos Not Supported",
675 	"Instant Passed",
676 	"Pairing With Unit Key Not Supported",
677 	"Different Transaction Collision",
678 	"Qos Unacceptable Parameter",
679 	"Qos Rejected",
680 	"Classification Not Supported",
681 	"Insufficient Security",
682 	"Parameter Out Of Range",
683 	"Reserved",
684 	"Role Switch Pending",
685 	"Reserved",
686 	"Slot Violation",
687 	"Role Switch Failed",
688 	"Extended Inquiry Response Too Large",
689 	"Simple Pairing Not Supported By Host",
690 	"Host Busy Pairing"
691 };
692 
693 
694 const char* hciVersion[] = { "1.0B" , "1.1 " , "1.2 " , "2.0 " , "2.1 "};
695 const char* lmpVersion[] = { "1.0 " , "1.1 " , "1.2 " , "2.0 " , "2.1 "};
696 
697 
698 #if 0
699 #pragma mark -
700 #endif
701 
702 
703 const char*
704 BluetoothHciVersion(uint16 ver)
705 {
706 	return hciVersion[ver];
707 }
708 
709 
710 const char*
711 BluetoothLmpVersion(uint16 ver)
712 {
713 	return lmpVersion[ver];
714 }
715 
716 
717 const char*
718 BluetoothCommandOpcode(uint16 opcode)
719 {
720 
721 	// NOTE: BT implementations beyond 2.1
722 	// could specify new commands with OCF numbers
723 	// beyond the boundaries of the arrays and crash.
724 	// But only our stack could issue them so its under
725 	// our control.
726 	switch (GET_OPCODE_OGF(opcode)) {
727 		case OGF_LINK_CONTROL:
728 			return linkControlCommands[GET_OPCODE_OCF(opcode) - 1];
729 			break;
730 
731 		case OGF_LINK_POLICY:
732 			return linkPolicyCommands[GET_OPCODE_OCF(opcode) - 1];
733 			break;
734 
735 		case OGF_CONTROL_BASEBAND:
736 			return controllerBasebandCommands[GET_OPCODE_OCF(opcode) - 1];
737 			break;
738 
739 		case OGF_INFORMATIONAL_PARAM:
740 			return informationalParametersCommands[GET_OPCODE_OCF(opcode) - 1];
741 			break;
742 
743 		case OGF_STATUS_PARAM:
744 			return statusParametersCommands[GET_OPCODE_OCF(opcode) - 1];
745 			break;
746 
747 		case OGF_TESTING_CMD:
748 			return testingCommands[GET_OPCODE_OCF(opcode) - 1];
749 			break;
750 		case OGF_VENDOR_CMD:
751 			return "Vendor specific command";
752 			break;
753 		default:
754 			return "Unknown command";
755 			break;
756 	}
757 
758 }
759 
760 
761 const char*
762 BluetoothEvent(uint8 event)
763 {
764 	if (event < sizeof(bluetoothEvents) / sizeof(const char*))
765 		return bluetoothEvents[event - 1];
766 	else
767 		return "Event out of Range!";
768 }
769 
770 
771 const char*
772 BluetoothManufacturer(uint16 manufacturer)
773 {
774 	if (manufacturer < sizeof(bluetoothManufacturers) / sizeof(const char*))
775 		return bluetoothManufacturers[manufacturer];
776 	else if (manufacturer == 0xFFFF)
777 		return "internal use";
778 	else
779 		return "not assigned";
780 }
781 
782 
783 const char*
784 BluetoothError(uint8 error)
785 {
786 	if (error < sizeof(bluetoothErrors) / sizeof(const char*))
787 		return bluetoothErrors[error];
788 	else
789 		return "not specified";
790 }
791