diff --git a/example/Makefile.am b/example/Makefile.am index 49f0c77a3..6c24e053a 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = test test_SOURCES = test.c ../src/btstack.c ../src/hci.c \ ../src/l2cap.c ../src/linked_list.c ../src/run_loop.c \ - ../src/hci_dump.c ../src/socket_connection.c + ../src/hci_dump.c ../src/hci_cmds.c ../src/socket_connection.c diff --git a/project.xcodeproj/project.pbxproj b/project.xcodeproj/project.pbxproj index eebac9ce1..8a9dc2ff8 100644 --- a/project.xcodeproj/project.pbxproj +++ b/project.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 9C00F7321017ACC3008DAB17 /* socket_connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7301017ACC3008DAB17 /* socket_connection.c */; }; + 9C00F7D71019082F008DAB17 /* hci_cmds.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7D61019082F008DAB17 /* hci_cmds.c */; }; + 9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7D61019082F008DAB17 /* hci_cmds.c */; }; 9C1F0E9A0FDAE023008F472F /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C1F0E980FDAE023008F472F /* run_loop.c */; }; 9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; }; 9C20720F10025E0500A07EA4 /* libusb-1.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C20720E10025E0500A07EA4 /* libusb-1.0.dylib */; }; @@ -45,6 +47,8 @@ 8DD76FB20486AB0100D96B5E /* project */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = project; sourceTree = BUILT_PRODUCTS_DIR; }; 9C00F7301017ACC3008DAB17 /* socket_connection.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = socket_connection.c; path = src/socket_connection.c; sourceTree = ""; }; 9C00F7311017ACC3008DAB17 /* socket_connection.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = socket_connection.h; path = src/socket_connection.h; sourceTree = ""; }; + 9C00F7D51019082F008DAB17 /* hci_cmds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hci_cmds.h; path = src/hci_cmds.h; sourceTree = ""; }; + 9C00F7D61019082F008DAB17 /* hci_cmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hci_cmds.c; path = src/hci_cmds.c; sourceTree = ""; }; 9C1F0E980FDAE023008F472F /* run_loop.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = run_loop.c; path = src/run_loop.c; sourceTree = ""; }; 9C1F0E990FDAE023008F472F /* run_loop.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = run_loop.h; path = src/run_loop.h; sourceTree = ""; }; 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_usb.c; path = src/hci_transport_usb.c; sourceTree = ""; }; @@ -132,6 +136,8 @@ 9C1F0E980FDAE023008F472F /* run_loop.c */, 9C00F7301017ACC3008DAB17 /* socket_connection.c */, 9C00F7311017ACC3008DAB17 /* socket_connection.h */, + 9C00F7D51019082F008DAB17 /* hci_cmds.h */, + 9C00F7D61019082F008DAB17 /* hci_cmds.c */, ); name = Source; sourceTree = ""; @@ -232,6 +238,7 @@ 9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */, 9C7B5AC0100BD3340065D87E /* linked_list.c in Sources */, 9C00F7321017ACC3008DAB17 /* socket_connection.c in Sources */, + 9C00F7D71019082F008DAB17 /* hci_cmds.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -247,6 +254,7 @@ 9C7B5D0D100FC9CE0065D87E /* linked_list.c in Sources */, 9C7B5D0E100FC9D00065D87E /* run_loop.c in Sources */, 9C7B5D12100FC9F00065D87E /* l2cap.c in Sources */, + 9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/Makefile.am b/src/Makefile.am index 8ab5d686c..d5828ffd2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ BTdaemon_SOURCES = \ bt_control_iphone.c \ daemon.c \ hci.c \ + hci_cmds.c \ hci_dump.c \ hci_transport_h4.c \ $(usb_support) \ @@ -20,6 +21,7 @@ include_HEADERS = \ bt_control.h \ bt_control_iphone.h \ hci.h \ + hci_cmds.h \ hci_dump.h \ hci_transport.h \ hci_transport_h4.h \ diff --git a/src/hci.c b/src/hci.c index 9216df67f..8514a2db0 100644 --- a/src/hci.c +++ b/src/hci.c @@ -10,108 +10,7 @@ #include #include #include "hci.h" - -/** - * Link Control Commands - */ -hci_cmd_t hci_inquiry = { - OPCODE(OGF_LINK_CONTROL, 0x01), "311" - // LAP, Inquiry length, Num_responses -}; -hci_cmd_t hci_inquiry_cancel = { - OPCODE(OGF_LINK_CONTROL, 0x02), "" - // no params -}; -hci_cmd_t hci_create_connection = { - OPCODE(OGF_LINK_CONTROL, 0x05), "B21121" - // BD_ADDR, Packet_Type, Page_Scan_Repetition_Mode, Reserved, Clock_Offset, Allow_Role_Switch -}; - -hci_cmd_t hci_accept_connection_request = { - OPCODE(OGF_LINK_CONTROL, 0x09), "B1" - // BD_ADDR, Role: become master, stay slave -}; -hci_cmd_t hci_link_key_request_negative_reply = { - OPCODE(OGF_LINK_CONTROL, 0x0c), "B" -}; -hci_cmd_t hci_pin_code_request_reply = { - OPCODE(OGF_LINK_CONTROL, 0x0d), "B1P" - // BD_ADDR, pin length, PIN: c-string -}; -hci_cmd_t hci_remote_name_request = { - OPCODE(OGF_LINK_CONTROL, 0x19), "B112" - // BD_ADDR, Page_Scan_Repetition_Mode, Reserved, Clock_Offset -}; - hci_cmd_t hci_remote_name_request_cancel = { - OPCODE(OGF_LINK_CONTROL, 0x1A), "B" - // BD_ADDR -}; - -/** - * Controller & Baseband Commands - */ -hci_cmd_t hci_set_event_mask = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x01), "44" - // event_mask lower 4 octets, higher 4 bytes -}; -hci_cmd_t hci_reset = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x03), "" - // no params -}; -hci_cmd_t hci_delete_stored_link_key = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x12), "B1" - // BD_ADDR, Delete_All_Flag -}; -hci_cmd_t hci_write_local_name = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x13), "N" - // Local name (UTF-8, Null Terminated, max 248 octets) -}; -hci_cmd_t hci_write_page_timeout = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x18), "2" - // Page_Timeout * 0.625 ms -}; -hci_cmd_t hci_write_scan_enable = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x1A), "1" - // Scan_enable: no, inq, page, inq+page -}; -hci_cmd_t hci_write_authentication_enable = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x20), "1" - // Authentication_Enable -}; -hci_cmd_t hci_write_class_of_device = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x24), "3" - // Class of Device -}; -hci_cmd_t hci_host_buffer_size = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x33), "2122" - // Host_ACL_Data_Packet_Length:, Host_Synchronous_Data_Packet_Length:, Host_Total_Num_ACL_Data_Packets:, Host_Total_Num_Synchronous_Data_Packets: -}; - -hci_cmd_t hci_write_inquiry_mode = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x45), "1" - // Inquiry mode: 0x00 = standard, 0x01 = with RSSI, 0x02 = extended -}; - -hci_cmd_t hci_write_extended_inquiry_response = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x52), "1E" - // FEC_Required, Exstended Inquiry Response -}; - -hci_cmd_t hci_write_simple_pairing_mode = { - OPCODE(OGF_CONTROLLER_BASEBAND, 0x56), "1" - // mode: 0 = off, 1 = on -}; - -hci_cmd_t hci_read_bd_addr = { - OPCODE(OGF_INFORMATIONAL_PARAMETERS, 0x09), "" - // no params -}; - -hci_cmd_t hci_get_btstack_state = { - OPCODE(OGF_BTSTACK, HCI_BTSTACK_GET_STATE), "" - // no params -> -}; - +#include "hci_dump.h" // the stack is here static hci_stack_t hci_stack; @@ -371,80 +270,6 @@ int hci_send_cmd_packet(uint8_t *packet, int size){ return 0; } -uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, va_list argptr){ - - hci_cmd_buffer[0] = cmd->opcode & 0xff; - hci_cmd_buffer[1] = cmd->opcode >> 8; - int pos = 3; - - const char *format = cmd->format; - uint16_t word; - uint32_t longword; - uint8_t * ptr; - while (*format) { - switch(*format) { - case '1': // 8 bit value - case '2': // 16 bit value - case 'H': // hci_handle - word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs - hci_cmd_buffer[pos++] = word & 0xff; - if (*format == '2') { - hci_cmd_buffer[pos++] = word >> 8; - } else if (*format == 'H') { - // TODO - } - break; - case '3': - case '4': - longword = va_arg(argptr, uint32_t); - // longword = va_arg(argptr, int); - hci_cmd_buffer[pos++] = longword; - hci_cmd_buffer[pos++] = longword >> 8; - hci_cmd_buffer[pos++] = longword >> 16; - if (*format == '4'){ - hci_cmd_buffer[pos++] = longword >> 24; - } - break; - case 'B': // bt-addr - ptr = va_arg(argptr, uint8_t *); - hci_cmd_buffer[pos++] = ptr[5]; - hci_cmd_buffer[pos++] = ptr[4]; - hci_cmd_buffer[pos++] = ptr[3]; - hci_cmd_buffer[pos++] = ptr[2]; - hci_cmd_buffer[pos++] = ptr[1]; - hci_cmd_buffer[pos++] = ptr[0]; - break; - case 'P': // c string passed as pascal string with leading 1-byte len - ptr = va_arg(argptr, uint8_t *); - memcpy(&hci_cmd_buffer[pos], ptr, 16); - pos += 16; - break; - case 'N': // UTF-8 string, null terminated - ptr = va_arg(argptr, uint8_t *); - memcpy(&hci_cmd_buffer[pos], ptr, 248); - pos += 248; - break; - case 'E': // Extended Inquiry Information 240 octets - ptr = va_arg(argptr, uint8_t *); - memcpy(&hci_cmd_buffer[pos], ptr, 240); - pos += 240; - break; - default: - break; - } - format++; - }; - hci_cmd_buffer[2] = pos - 3; - return pos; -} - -uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...){ - va_list argptr; - va_start(argptr, cmd); - uint16_t len = hci_create_cmd_internal(hci_cmd_buffer, cmd, argptr); - va_end(argptr); - return len; -} /** * pre: numcmds >= 0 - it's allowed to send a command to the controller diff --git a/src/hci.h b/src/hci.h index 945a901cd..32208d274 100644 --- a/src/hci.h +++ b/src/hci.h @@ -11,6 +11,7 @@ #include #include +#include "hci_cmds.h" #include "hci_transport.h" #include "bt_control.h" @@ -19,26 +20,12 @@ #define READ_BT_24( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16)) #define READ_BT_32( buffer, pos) ( ((uint32_t) buffer[pos]) | (((uint32_t)buffer[pos+1]) << 8) | (((uint32_t)buffer[pos+2]) << 16) | (((uint32_t) buffer[pos+3])) << 24) -// calculate combined ogf/ocf value -#define OPCODE(ogf, ocf) (ocf | ogf << 10) - -// get HCI CMD OGF -#define READ_CMD_OGF(buffer) (buffer[1] >> 2) -#define READ_CMD_OCF(buffer) ((buffer[1] & 0x03) << 8 | buffer[0]) - // packet header lengh #define HCI_CMD_DATA_PKT_HDR 0x03 #define HCI_ACL_DATA_PKT_HDR 0x04 #define HCI_SCO_DATA_PKT_HDR 0x03 #define HCI_EVENT_PKT_HDR 0x02 -// OGFs -#define OGF_LINK_CONTROL 0x01 -#define OGF_CONTROLLER_BASEBAND 0x03 -#define OGF_INFORMATIONAL_PARAMETERS 0x04 -#define OGF_BTSTACK 0x3d -#define OGF_VENDOR 0x3f - // Events from host controller to host #define HCI_EVENT_INQUIRY_COMPLETE 0x01 #define HCI_EVENT_INQUIRY_RESULT 0x02 @@ -75,12 +62,8 @@ #define HCI_EVENT_BTSTACK_WORKING 0x80 #define HCI_EVENT_BTSTACK_STATE 0x81 -// cmds for BTstack -#define HCI_BTSTACK_GET_STATE 0x01 - #define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode) - /** * Default INQ Mode */ @@ -115,11 +98,6 @@ typedef enum { HCI_STATE_HALTING } HCI_STATE; -typedef struct { - uint16_t opcode; - const char *format; -} hci_cmd_t; - typedef enum { SEND_NEGATIVE_LINK_KEY_REQUEST = 1 << 0, SEND_PIN_CODE_RESPONSE = 1 << 1 @@ -185,9 +163,9 @@ uint32_t hci_run(); void hexdump(void *data, int size); // create and send hci command packets based on a template and a list of parameters -uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, va_list argptr); -uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...); int hci_send_cmd(hci_cmd_t *cmd, ...); + +// send complete CMD packet int hci_send_cmd_packet(uint8_t *packet, int size); // send ACL packet @@ -198,28 +176,3 @@ extern void bt_store_16(uint8_t *buffer, uint16_t pos, uint16_t value); extern void bt_store_32(uint8_t *buffer, uint16_t pos, uint32_t value); extern void bt_flip_addr(bd_addr_t dest, bd_addr_t src); -// HCI Commands - see hci.c for info on parameters -extern hci_cmd_t hci_inquiry; -extern hci_cmd_t hci_inquiry_cancel; -extern hci_cmd_t hci_link_key_request_negative_reply; -extern hci_cmd_t hci_pin_code_request_reply; -extern hci_cmd_t hci_set_event_mask; -extern hci_cmd_t hci_reset; -extern hci_cmd_t hci_create_connection; -extern hci_cmd_t hci_host_buffer_size; -extern hci_cmd_t hci_write_authentication_enable; -extern hci_cmd_t hci_write_local_name; -extern hci_cmd_t hci_write_page_timeout; -extern hci_cmd_t hci_write_class_of_device; -extern hci_cmd_t hci_remote_name_request; -extern hci_cmd_t hci_remote_name_request_cancel; -extern hci_cmd_t hci_read_bd_addr; -extern hci_cmd_t hci_delete_stored_link_key; -extern hci_cmd_t hci_write_scan_enable; -extern hci_cmd_t hci_accept_connection_request; -extern hci_cmd_t hci_write_inquiry_mode; -extern hci_cmd_t hci_write_extended_inquiry_response; -extern hci_cmd_t hci_write_simple_pairing_mode; - -// BTSTACK client/server commands - see hci.c for info on parameters -extern hci_cmd_t hci_get_btstack_state; \ No newline at end of file diff --git a/src/hci_cmds.c b/src/hci_cmds.c new file mode 100644 index 000000000..e6822712e --- /dev/null +++ b/src/hci_cmds.c @@ -0,0 +1,201 @@ +/* + * hci_cmds.c + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#include "hci_cmds.h" + +/** + * construct HCI Command based on template + * + * Format: + * 1,2,3,4: one to four byte value + * H: HCI connection handle + * B: Bluetooth Baseband Address (BD_ADDR) + * P: 16 byte Pairing code + * N: Name up to 248 chars + * E: Extended Inquiry Result + */ +uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, va_list argptr){ + + hci_cmd_buffer[0] = cmd->opcode & 0xff; + hci_cmd_buffer[1] = cmd->opcode >> 8; + int pos = 3; + + const char *format = cmd->format; + uint16_t word; + uint32_t longword; + uint8_t * ptr; + while (*format) { + switch(*format) { + case '1': // 8 bit value + case '2': // 16 bit value + case 'H': // hci_handle + word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs + hci_cmd_buffer[pos++] = word & 0xff; + if (*format == '2') { + hci_cmd_buffer[pos++] = word >> 8; + } else if (*format == 'H') { + // TODO + } + break; + case '3': + case '4': + longword = va_arg(argptr, uint32_t); + // longword = va_arg(argptr, int); + hci_cmd_buffer[pos++] = longword; + hci_cmd_buffer[pos++] = longword >> 8; + hci_cmd_buffer[pos++] = longword >> 16; + if (*format == '4'){ + hci_cmd_buffer[pos++] = longword >> 24; + } + break; + case 'B': // bt-addr + ptr = va_arg(argptr, uint8_t *); + hci_cmd_buffer[pos++] = ptr[5]; + hci_cmd_buffer[pos++] = ptr[4]; + hci_cmd_buffer[pos++] = ptr[3]; + hci_cmd_buffer[pos++] = ptr[2]; + hci_cmd_buffer[pos++] = ptr[1]; + hci_cmd_buffer[pos++] = ptr[0]; + break; + case 'P': // c string passed as pascal string with leading 1-byte len + ptr = va_arg(argptr, uint8_t *); + memcpy(&hci_cmd_buffer[pos], ptr, 16); + pos += 16; + break; + case 'N': // UTF-8 string, null terminated + ptr = va_arg(argptr, uint8_t *); + memcpy(&hci_cmd_buffer[pos], ptr, 248); + pos += 248; + break; + case 'E': // Extended Inquiry Information 240 octets + ptr = va_arg(argptr, uint8_t *); + memcpy(&hci_cmd_buffer[pos], ptr, 240); + pos += 240; + break; + default: + break; + } + format++; + }; + hci_cmd_buffer[2] = pos - 3; + return pos; +} + +/** + * construct HCI Command based on template + * + * mainly calls hci_create_cmd_internal + */ +uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...){ + va_list argptr; + va_start(argptr, cmd); + uint16_t len = hci_create_cmd_internal(hci_cmd_buffer, cmd, argptr); + va_end(argptr); + return len; +} + + +/** + * Link Control Commands + */ +hci_cmd_t hci_inquiry = { +OPCODE(OGF_LINK_CONTROL, 0x01), "311" +// LAP, Inquiry length, Num_responses +}; +hci_cmd_t hci_inquiry_cancel = { +OPCODE(OGF_LINK_CONTROL, 0x02), "" +// no params +}; +hci_cmd_t hci_create_connection = { +OPCODE(OGF_LINK_CONTROL, 0x05), "B21121" +// BD_ADDR, Packet_Type, Page_Scan_Repetition_Mode, Reserved, Clock_Offset, Allow_Role_Switch +}; + +hci_cmd_t hci_accept_connection_request = { +OPCODE(OGF_LINK_CONTROL, 0x09), "B1" +// BD_ADDR, Role: become master, stay slave +}; +hci_cmd_t hci_link_key_request_negative_reply = { +OPCODE(OGF_LINK_CONTROL, 0x0c), "B" +}; +hci_cmd_t hci_pin_code_request_reply = { +OPCODE(OGF_LINK_CONTROL, 0x0d), "B1P" +// BD_ADDR, pin length, PIN: c-string +}; +hci_cmd_t hci_remote_name_request = { +OPCODE(OGF_LINK_CONTROL, 0x19), "B112" +// BD_ADDR, Page_Scan_Repetition_Mode, Reserved, Clock_Offset +}; +hci_cmd_t hci_remote_name_request_cancel = { +OPCODE(OGF_LINK_CONTROL, 0x1A), "B" +// BD_ADDR +}; + +/** + * Controller & Baseband Commands + */ +hci_cmd_t hci_set_event_mask = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x01), "44" +// event_mask lower 4 octets, higher 4 bytes +}; +hci_cmd_t hci_reset = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x03), "" +// no params +}; +hci_cmd_t hci_delete_stored_link_key = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x12), "B1" +// BD_ADDR, Delete_All_Flag +}; +hci_cmd_t hci_write_local_name = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x13), "N" +// Local name (UTF-8, Null Terminated, max 248 octets) +}; +hci_cmd_t hci_write_page_timeout = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x18), "2" +// Page_Timeout * 0.625 ms +}; +hci_cmd_t hci_write_scan_enable = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x1A), "1" +// Scan_enable: no, inq, page, inq+page +}; +hci_cmd_t hci_write_authentication_enable = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x20), "1" +// Authentication_Enable +}; +hci_cmd_t hci_write_class_of_device = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x24), "3" +// Class of Device +}; +hci_cmd_t hci_host_buffer_size = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x33), "2122" +// Host_ACL_Data_Packet_Length:, Host_Synchronous_Data_Packet_Length:, Host_Total_Num_ACL_Data_Packets:, Host_Total_Num_Synchronous_Data_Packets: +}; + +hci_cmd_t hci_write_inquiry_mode = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x45), "1" +// Inquiry mode: 0x00 = standard, 0x01 = with RSSI, 0x02 = extended +}; + +hci_cmd_t hci_write_extended_inquiry_response = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x52), "1E" +// FEC_Required, Exstended Inquiry Response +}; + +hci_cmd_t hci_write_simple_pairing_mode = { +OPCODE(OGF_CONTROLLER_BASEBAND, 0x56), "1" +// mode: 0 = off, 1 = on +}; + +hci_cmd_t hci_read_bd_addr = { +OPCODE(OGF_INFORMATIONAL_PARAMETERS, 0x09), "" +// no params +}; + +hci_cmd_t hci_get_btstack_state = { +OPCODE(OGF_BTSTACK, HCI_BTSTACK_GET_STATE), "" +// no params -> +}; + diff --git a/src/hci_cmds.h b/src/hci_cmds.h new file mode 100644 index 000000000..0b5bac22a --- /dev/null +++ b/src/hci_cmds.h @@ -0,0 +1,67 @@ +/* + * hci_cmds.h + * + * Created by Matthias Ringwald on 7/23/09. + */ + +#pragma once + +#include +#include +#include + +// calculate combined ogf/ocf value +#define OPCODE(ogf, ocf) (ocf | ogf << 10) + +// get HCI CMD OGF +#define READ_CMD_OGF(buffer) (buffer[1] >> 2) +#define READ_CMD_OCF(buffer) ((buffer[1] & 0x03) << 8 | buffer[0]) + +// OGFs +#define OGF_LINK_CONTROL 0x01 +#define OGF_CONTROLLER_BASEBAND 0x03 +#define OGF_INFORMATIONAL_PARAMETERS 0x04 +#define OGF_BTSTACK 0x3d +#define OGF_VENDOR 0x3f + +// cmds for BTstack +#define HCI_BTSTACK_GET_STATE 0x01 + + +/** + * compact HCI Command packet description + */ + typedef struct { + uint16_t opcode; + const char *format; +} hci_cmd_t; + +// create and send hci command packets based on a template and a list of parameters +uint16_t hci_create_cmd(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, ...); +uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, va_list argptr); + +// HCI Commands - see hci_cmds.c for info on parameters +extern hci_cmd_t hci_inquiry; +extern hci_cmd_t hci_inquiry_cancel; +extern hci_cmd_t hci_link_key_request_negative_reply; +extern hci_cmd_t hci_pin_code_request_reply; +extern hci_cmd_t hci_set_event_mask; +extern hci_cmd_t hci_reset; +extern hci_cmd_t hci_create_connection; +extern hci_cmd_t hci_host_buffer_size; +extern hci_cmd_t hci_write_authentication_enable; +extern hci_cmd_t hci_write_local_name; +extern hci_cmd_t hci_write_page_timeout; +extern hci_cmd_t hci_write_class_of_device; +extern hci_cmd_t hci_remote_name_request; +extern hci_cmd_t hci_remote_name_request_cancel; +extern hci_cmd_t hci_read_bd_addr; +extern hci_cmd_t hci_delete_stored_link_key; +extern hci_cmd_t hci_write_scan_enable; +extern hci_cmd_t hci_accept_connection_request; +extern hci_cmd_t hci_write_inquiry_mode; +extern hci_cmd_t hci_write_extended_inquiry_response; +extern hci_cmd_t hci_write_simple_pairing_mode; + +// BTSTACK client/server commands - see hci.c for info on parameters +extern hci_cmd_t hci_get_btstack_state; \ No newline at end of file