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