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.
7 #include "CommandManager.h"
10 #include <bluetooth/bluetooth_error.h>
11 #include <bluetooth/debug.h>
13 inline void* buildCommand(uint8 ogf
, uint8 ocf
, void** param
, size_t psize
,
17 struct hci_command_header
* header
;
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
);
24 size_t* size
= (size_t*)malloc(psize
+ sizeof(struct hci_command_header
)
26 *outsize
= psize
+ sizeof(struct hci_command_header
) + sizeof(size_t);
28 *size
= psize
+ sizeof(struct hci_command_header
);
29 header
= (struct hci_command_header
*) (((uint8
*)size
)+4);
35 header
->opcode
= B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf
, ocf
));
38 if (param
!= NULL
&& psize
!= 0) {
39 *param
= ((uint8
*)header
) + sizeof(struct hci_command_header
);
42 #ifdef BT_IOCTLS_PASS_SIZE
50 // This is for request that only require a Command complete in reply.
52 // Propagate to ReadBufferSize => reply stored in server side
53 // ReadLocalVersion => reply stored in server side
56 // Request that do not need any input parameter
57 // Output reply can be fit in 32 bits field without talking status into account
59 NonParameterCommandRequest(uint8 ofg
, uint8 ocf
, int32
* result
, hci_id hId
,
60 BMessenger
* messenger
)
63 int8 bt_status
= BT_ERROR
;
65 BluetoothCommand
<> simpleCommand(ofg
, ocf
);
67 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
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
));
76 if (messenger
->SendMessage(&request
, &reply
) == B_OK
) {
77 reply
.FindInt8("status", &bt_status
);
79 reply
.FindInt32("result", result
);
87 #pragma mark - CONTROL BASEBAND -
91 void* buildReset(size_t* outsize
)
94 return buildCommand(OGF_CONTROL_BASEBAND
, OCF_RESET
,
99 void* buildReadLocalName(size_t* outsize
)
102 return buildCommand(OGF_CONTROL_BASEBAND
, OCF_READ_LOCAL_NAME
,
107 void* buildReadClassOfDevice(size_t* outsize
)
110 return buildCommand(OGF_CONTROL_BASEBAND
, OCF_READ_CLASS_OF_DEV
,
115 void* buildReadScan(size_t* outsize
)
118 return buildCommand(OGF_CONTROL_BASEBAND
, OCF_READ_SCAN_ENABLE
,
123 void* buildWriteScan(uint8 scanmode
, size_t* outsize
)
126 struct hci_write_scan_enable
* param
;
127 void* command
= buildCommand(OGF_CONTROL_BASEBAND
, OCF_WRITE_SCAN_ENABLE
,
128 (void**) ¶m
, sizeof(struct hci_write_scan_enable
), outsize
);
131 if (command
!= NULL
) {
132 param
->scan
= scanmode
;
140 #pragma mark - LINK CONTROL -
144 void* buildRemoteNameRequest(bdaddr_t bdaddr
, uint8 pscan_rep_mode
,
145 uint16 clock_offset
, size_t* outsize
)
148 struct hci_remote_name_request
* param
;
149 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_REMOTE_NAME_REQUEST
,
150 (void**)¶m
, sizeof(struct hci_remote_name_request
), outsize
);
152 if (command
!= NULL
) {
153 param
->bdaddr
= bdaddr
;
154 param
->pscan_rep_mode
= pscan_rep_mode
;
155 param
->clock_offset
= clock_offset
;
162 void* buildInquiry(uint32 lap
, uint8 length
, uint8 num_rsp
, size_t* outsize
)
165 struct hci_cp_inquiry
* param
;
166 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_INQUIRY
,
167 (void**) ¶m
, sizeof(struct hci_cp_inquiry
), outsize
);
169 if (command
!= NULL
) {
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
;
182 void* buildInquiryCancel(size_t* outsize
)
185 return buildCommand(OGF_LINK_CONTROL
, OCF_INQUIRY_CANCEL
, NULL
, 0, outsize
);
189 void* buildPinCodeRequestReply(bdaddr_t bdaddr
, uint8 length
, char pincode
[16],
193 struct hci_cp_pin_code_reply
* param
;
195 if (length
> HCI_PIN_SIZE
) // PinCode cannot be longer than 16
198 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_PIN_CODE_REPLY
,
199 (void**)¶m
, sizeof(struct hci_cp_pin_code_reply
), outsize
);
201 if (command
!= NULL
) {
202 param
->bdaddr
= bdaddr
;
203 param
->pin_len
= length
;
204 memcpy(¶m
->pin_code
, pincode
, length
);
211 void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr
, size_t* outsize
)
214 struct hci_cp_pin_code_neg_reply
* param
;
216 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_PIN_CODE_NEG_REPLY
,
217 (void**) ¶m
, sizeof(struct hci_cp_pin_code_neg_reply
), outsize
);
219 if (command
!= NULL
) {
221 param
->bdaddr
= bdaddr
;
229 void* buildAcceptConnectionRequest(bdaddr_t bdaddr
, uint8 role
, size_t* outsize
)
232 struct hci_cp_accept_conn_req
* param
;
234 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_ACCEPT_CONN_REQ
,
235 (void**) ¶m
, sizeof(struct hci_cp_accept_conn_req
), outsize
);
237 if (command
!= NULL
) {
238 param
->bdaddr
= bdaddr
;
246 void* buildRejectConnectionRequest(bdaddr_t bdaddr
, size_t* outsize
)
249 struct hci_cp_reject_conn_req
* param
;
251 void* command
= buildCommand(OGF_LINK_CONTROL
, OCF_REJECT_CONN_REQ
,
252 (void**)¶m
, sizeof(struct hci_cp_reject_conn_req
),
255 if (command
!= NULL
) {
256 param
->bdaddr
= bdaddr
;
264 #pragma mark - INFORMATIONAL_PARAM -
267 void* buildReadLocalVersionInformation(size_t* outsize
)
270 return buildCommand(OGF_INFORMATIONAL_PARAM
, OCF_READ_LOCAL_VERSION
,
275 void* buildReadBufferSize(size_t* outsize
)
278 return buildCommand(OGF_INFORMATIONAL_PARAM
, OCF_READ_BUFFER_SIZE
,
283 void* buildReadBdAddr(size_t* outsize
)
286 return buildCommand(OGF_INFORMATIONAL_PARAM
, OCF_READ_BD_ADDR
,
291 const char* bluetoothManufacturers
[] = {
292 "Ericsson Technology Licensing",
293 "Nokia Mobile Phones",
301 "Infineon Technologies AG",
302 "Cambridge Silicon Radio",
305 "Texas Instruments Inc.",
306 "Parthus Technologies Inc.",
307 "Broadcom Corporation",
308 "Mitel Semiconductor",
312 "Mitsubishi Electric Corporation",
314 "KC Technology Inc.",
317 "Rohde & Schwartz GmbH & Co. KG",
319 "Signia Technologies, Inc.",
320 "Conexant Systems Inc.",
327 "WavePlus Technology Co., Ltd.",
329 "Philips Semiconductors",
334 "Symbol Technologies, Inc.",
336 "Macronix International Co. Ltd.",
339 "MewTel Technology Inc.",
340 "ST Microelectronics",
342 "Red-M (Communications) Ltd",
344 "Computer Access Technology Corporation (CATC)",
345 "Eclipse (HQ España) S.L.",
346 "Renesas Technology Corp.",
347 "Mobilian Corporation",
349 "Integrated System Solution Corp.",
350 "Matsushita Electric Industrial Co., Ltd.",
351 "Gennum Corporation",
352 "Research In Motion",
354 "Systems and Chips, Inc",
355 "Bluetooth SIG, Inc",
356 "Seiko Epson Corporation",
357 "Integrated Silicon Solution Taiwain, Inc.",
358 "CONWISE Technology Corporation Ltd",
360 "Socket Communications",
361 "Atheros Communications, Inc.",
363 "Bluegiga", /* (tentative) */
364 "Marvell Technology Group Ltd.",
366 "Accel Semiconductor Ltd.",
367 "Continental Automotive Systems",
369 "Staccato Communications, Inc."
373 const char* linkControlCommands
[] = {
376 "Periodic Inquiry Mode",
377 "Exit Periodic Inquiry Mode",
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",
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",
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",
424 "Remote OOB Data Request Negative Reply",
425 "IO Capabilities Response Negative Reply"
429 const char* linkPolicyCommands
[] = {
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",
450 const char* controllerBasebandCommands
[] = {
461 "Create New Unit Key",
463 "Read Stored Link Key",
467 "Write Stored Link Key",
468 "Delete Stored Link Key",
471 "Read Connection Accept Timeout",
472 "Write Connection Accept Timeout",
474 "Write Page Timeout",
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",
499 "Set Host Controller To Host Flow Control",
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",
516 "Read Inquiry Scan Type",
517 "Write Inquiry Scan Type",
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",
531 "Read Extended Inquiry Response",
532 "Write Extended Inquiry Response",
533 "Refresh Encryption Key",
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",
546 "Send Keypress Notification"
550 const char* informationalParametersCommands
[] = {
551 "Read Local Version Information",
552 "Read Local Supported Commands",
553 "Read Local Supported Features",
554 "Read Local Extended Features",
557 "Read Country Code", // not 2.1
563 const char* statusParametersCommands
[] = {
564 "Read Failed Contact Counter",
565 "Reset Failed Contact Counter",
569 "Read AFH Channel Map",
574 const char* testingCommands
[] = {
575 "Read Loopback Mode",
576 "Write Loopback Mode",
577 "Enable Device Under Test Mode",
578 "Write Simple Pairing Debug Mode",
582 const char* bluetoothEvents
[] = {
587 "Disconnection Complete",
589 "Remote Name Request Complete",
591 "Change Conn Link Key Complete",
592 "Master Link Key Compl",
595 "Qos Setup Complete",
608 "Data Buffer Overflow",
610 "Read Clock Offset Compl",
611 "Con Pkt Type Changed",
614 "Page Scan Rep Mode Change",
615 "Flow Specification",
616 "Inquiry Result With Rssi",
617 "Remote Extended Features",
626 "Synchronous Connection Completed",
627 "Synchronous Connection Changed",
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",
636 "Simple Pairing Complete",
638 "Link Supervision Timeout Changed",
639 "Enhanced Flush Complete",
642 "Keypress Notification",
643 "Remote Host Supported Features Notification"
647 const char* bluetoothErrors
[] = {
653 "Authentication Failure",
654 "Pin Or Key Missing",
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",
665 "Unsupported Feature",
666 "Invalid Parameters",
667 "Remote User Ended Connection",
668 "Remote Low Resources",
670 "Connection Terminated",
672 "Pairing Not Allowed",
674 "Unsupported Remote Feature",
675 "Sco Offset Rejected",
676 "Sco Interval Rejected",
678 "Invalid Lmp Parameters",
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",
689 "Pairing With Unit Key Not Supported",
690 "Different Transaction Collision",
691 "Qos Unacceptable Parameter",
693 "Classification Not Supported",
694 "Insufficient Security",
695 "Parameter Out Of Range",
697 "Role Switch Pending",
700 "Role Switch Failed",
701 "Extended Inquiry Response Too Large",
702 "Simple Pairing Not Supported By Host",
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 "};
717 BluetoothHciVersion(uint16 ver
)
720 return hciVersion
[ver
];
725 BluetoothLmpVersion(uint16 ver
)
728 return lmpVersion
[ver
];
733 BluetoothCommandOpcode(uint16 opcode
)
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
741 switch (GET_OPCODE_OGF(opcode
)) {
742 case OGF_LINK_CONTROL
:
743 return linkControlCommands
[GET_OPCODE_OCF(opcode
) - 1];
746 case OGF_LINK_POLICY
:
747 return linkPolicyCommands
[GET_OPCODE_OCF(opcode
) - 1];
750 case OGF_CONTROL_BASEBAND
:
751 return controllerBasebandCommands
[GET_OPCODE_OCF(opcode
) - 1];
754 case OGF_INFORMATIONAL_PARAM
:
755 return informationalParametersCommands
[GET_OPCODE_OCF(opcode
) - 1];
758 case OGF_STATUS_PARAM
:
759 return statusParametersCommands
[GET_OPCODE_OCF(opcode
) - 1];
762 case OGF_TESTING_CMD
:
763 return testingCommands
[GET_OPCODE_OCF(opcode
) - 1];
766 return "Vendor specific command";
769 return "Unknown command";
777 BluetoothEvent(uint8 event
)
780 if (event
< sizeof(bluetoothEvents
) / sizeof(const char*))
781 return bluetoothEvents
[event
- 1];
783 return "Event out of Range!";
788 BluetoothManufacturer(uint16 manufacturer
)
791 if (manufacturer
< sizeof(bluetoothManufacturers
) / sizeof(const char*))
792 return bluetoothManufacturers
[manufacturer
];
793 else if (manufacturer
== 0xFFFF)
794 return "internal use";
796 return "not assigned";
801 BluetoothError(uint8 error
)
804 if (error
< sizeof(bluetoothErrors
) / sizeof(const char*))
805 return bluetoothErrors
[error
];
807 return "not specified";