From a3cc218cd5f213922cd529ebfb5da5ba1b1f1aca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 1 Aug 2007 07:29:23 +0000 Subject: Add definitions and functions for Simple Pairing --- include/hci.h | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/hci_lib.h | 3 ++ src/hci.c | 107 +++++++++++++++++++++++++++++++------ 3 files changed, 248 insertions(+), 16 deletions(-) diff --git a/include/hci.h b/include/hci.h index eaab3964..a4f88146 100644 --- a/include/hci.h +++ b/include/hci.h @@ -188,6 +188,8 @@ enum { #define HCI_SLOT_VIOLATION 0x34 #define HCI_ROLE_SWITCH_FAILED 0x35 #define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 /* ACL flags */ #define ACL_CONT 0x01 @@ -249,6 +251,8 @@ enum { #define LMP_EDR_3S_ESCO 0x80 #define LMP_EXT_INQ 0x01 +#define LMP_SIMPLE_PAIR 0x08 +#define LMP_ENCAPS_PDU 0x10 #define LMP_ERR_DAT_REP 0x20 #define LMP_NFLUSH_PKTS 0x40 @@ -473,6 +477,49 @@ typedef struct { } __attribute__ ((packed)) reject_sync_conn_req_cp; #define REJECT_SYNC_CONN_REQ_CP_SIZE 7 +#define OCF_IO_CAPABILITY_REPLY 0x002B +typedef struct { + bdaddr_t bdaddr; + uint8_t capability; + uint8_t oob_data; + uint8_t authentication; +} __attribute__ ((packed)) io_capability_reply_cp; +#define IO_CAPABILITY_REPLY_CP_SIZE 9 + +#define OCF_USER_CONFIRM_REPLY 0x002C +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) user_confirm_reply_cp; +#define USER_CONFIRM_REPLY_CP_SIZE 6 + +#define OCF_USER_CONFIRM_NEG_REPLY 0x002D + +#define OCF_USER_PASSKEY_REPLY 0x002E +typedef struct { + bdaddr_t bdaddr; + uint32_t passkey; +} __attribute__ ((packed)) user_passkey_reply_cp; +#define USER_PASSKEY_REPLY_CP_SIZE 10 + +#define OCF_USER_PASSKEY_NEG_REPLY 0x002F + +#define OCF_REMOTE_OOB_DATA_REPLY 0x0030 +typedef struct { + bdaddr_t bdaddr; + uint8_t hash[16]; + uint8_t randomizer[16]; +} __attribute__ ((packed)) remote_oob_data_reply_cp; +#define REMOTE_OOB_DATA_REPLY_CP_SIZE 38 + +#define OCF_REMOTE_OOB_DATA_NEG_REPLY 0x0033 + +#define OCF_IO_CAPABILITY_NEG_REPLY 0x0034 +typedef struct { + bdaddr_t bdaddr; + uint8_t reason; +} __attribute__ ((packed)) io_capability_neg_reply_cp; +#define IO_CAPABILITY_NEG_REPLY_CP_SIZE 7 + /* Link Policy */ #define OGF_LINK_POLICY 0x02 @@ -980,6 +1027,31 @@ typedef struct { } __attribute__ ((packed)) refresh_encryption_key_rp; #define REFRESH_ENCRYPTION_KEY_RP_SIZE 1 +#define OCF_READ_SIMPLE_PAIRING_MODE 0x0055 +typedef struct { + uint8_t status; + uint8_t mode; +} __attribute__ ((packed)) read_simple_pairing_mode_rp; +#define READ_SIMPLE_PAIRING_MODE_RP_SIZE 2 + +#define OCF_WRITE_SIMPLE_PAIRING_MODE 0x0056 +typedef struct { + uint8_t mode; +} __attribute__ ((packed)) write_simple_pairing_mode_cp; +#define WRITE_SIMPLE_PAIRING_MODE_CP_SIZE 1 +typedef struct { + uint8_t status; +} __attribute__ ((packed)) write_simple_pairing_mode_rp; +#define WRITE_SIMPLE_PAIRING_MODE_RP_SIZE 1 + +#define OCF_READ_LOCAL_OOB_DATA 0x0057 +typedef struct { + uint8_t status; + uint8_t hash[16]; + uint8_t randomizer[16]; +} __attribute__ ((packed)) read_local_oob_data_rp; +#define READ_LOCAL_OOB_DATA_RP_SIZE 33 + #define OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL 0x0058 typedef struct { uint8_t status; @@ -1021,6 +1093,17 @@ typedef struct { } __attribute__ ((packed)) enhanced_flush_cp; #define ENHANCED_FLUSH_CP_SIZE 3 +#define OCF_SEND_KEYPRESS_NOTIFY 0x0060 +typedef struct { + bdaddr_t bdaddr; + uint8_t type; +} __attribute__ ((packed)) send_keypress_notify_cp; +#define SEND_KEYPRESS_NOTIFY_CP_SIZE 7 +typedef struct { + uint8_t status; +} __attribute__ ((packed)) send_keypress_notify_rp; +#define SEND_KEYPRESS_NOTIFY_RP_SIZE 1 + /* Informational Parameters */ #define OGF_INFO_PARAM 0x04 @@ -1141,6 +1224,22 @@ typedef struct { /* Testing commands */ #define OGF_TESTING_CMD 0x3e +#define OCF_READ_LOOPBACK_MODE 0x0001 + +#define OCF_WRITE_LOOPBACK_MODE 0x0002 + +#define OCF_ENABLE_DEVICE_UNDER_TEST_MODE 0x0003 + +#define OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE 0x0004 +typedef struct { + uint8_t mode; +} __attribute__ ((packed)) write_simple_pairing_debug_mode_cp; +#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_CP_SIZE 1 +typedef struct { + uint8_t status; +} __attribute__ ((packed)) write_simple_pairing_debug_mode_rp; +#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_RP_SIZE 1 + /* Vendor specific commands */ #define OGF_VENDOR_CMD 0x3f @@ -1468,6 +1567,47 @@ typedef struct { } __attribute__ ((packed)) evt_encryption_key_refresh_complete; #define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 +#define EVT_IO_CAPABILITY_REQUEST 0x31 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_io_capability_request; +#define EVT_IO_CAPABILITY_REQUEST_SIZE 6 + +#define EVT_IO_CAPABILITY_RESPONSE 0x32 +typedef struct { + bdaddr_t bdaddr; + uint8_t capability; + uint8_t oob_data; + uint8_t authentication; +} __attribute__ ((packed)) evt_io_capability_response; +#define EVT_IO_CAPABILITY_RESPONSE_SIZE 9 + +#define EVT_USER_CONFIRM_REQUEST 0x33 +typedef struct { + bdaddr_t bdaddr; + uint32_t passkey; +} __attribute__ ((packed)) evt_user_confirm_request; +#define EVT_USER_CONFIRM_REQUEST_SIZE 10 + +#define EVT_USER_PASSKEY_REQUEST 0x34 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_user_passkey_request; +#define EVT_USER_PASSKEY_REQUEST_SIZE 6 + +#define EVT_REMOTE_OOB_DATA_REQUEST 0x35 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_remote_oob_data_request; +#define EVT_REMOTE_OOB_DATA_REQUEST_SIZE 6 + +#define EVT_SIMPLE_PAIRING_COMPLETE 0x36 +typedef struct { + uint8_t status; + bdaddr_t bdaddr; +} __attribute__ ((packed)) evt_simple_pairing_complete; +#define EVT_SIMPLE_PAIRING_COMPLETE_SIZE 7 + #define EVT_LINK_SUPERVISION_TIMEOUT_CHANGED 0x38 typedef struct { uint16_t handle; @@ -1481,6 +1621,20 @@ typedef struct { } __attribute__ ((packed)) evt_enhanced_flush_complete; #define EVT_ENHANCED_FLUSH_COMPLETE_SIZE 2 +#define EVT_USER_PASSKEY_NOTIFY 0x3B +typedef struct { + bdaddr_t bdaddr; + uint32_t passkey; +} __attribute__ ((packed)) evt_user_passkey_notify; +#define EVT_USER_PASSKEY_NOTIFY_SIZE 10 + +#define EVT_KEYPRESS_NOTIFY 0x3C +typedef struct { + bdaddr_t bdaddr; + uint8_t type; +} __attribute__ ((packed)) evt_keypress_notify; +#define EVT_KEYPRESS_NOTIFY_SIZE 7 + #define EVT_REMOTE_HOST_FEATURES_NOTIFY 0x3D typedef struct { bdaddr_t bdaddr; diff --git a/include/hci_lib.h b/include/hci_lib.h index a784a08b..1215a62f 100644 --- a/include/hci_lib.h +++ b/include/hci_lib.h @@ -98,6 +98,9 @@ int hci_read_afh_mode(int dd, uint8_t *mode, int to); int hci_write_afh_mode(int dd, uint8_t mode, int to); int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to); int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to); +int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to); +int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to); +int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to); int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to); int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to); int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout, int to); diff --git a/src/hci.c b/src/hci.c index 04da6de5..d3e81d2c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -467,9 +467,9 @@ static hci_map commands_map[] = { { "Refresh Encryption Key", 138 }, { "Reserved", 139 }, { "Sniff Subrating", 140 }, - { "Unknown", 141 }, - { "Unknown", 142 }, - { "Unknown", 143 }, + { "Read Simple Pairing Mode", 141 }, + { "Write Simple Pairing Mode", 142 }, + { "Read Local OOB Data", 143 }, { "Read Inquiry Transmit Power Level", 144 }, { "Write Inquiry Transmit Power Level", 145 }, @@ -478,21 +478,21 @@ static hci_map commands_map[] = { { "Reserved", 148 }, { "Reserved", 149 }, { "Reserved", 150 }, - { "Unknown", 151 }, - - { "Unknown", 152 }, - { "Unknown", 153 }, - { "Unknown", 154 }, - { "Unknown", 155 }, - { "Unknown", 156 }, - { "Unknown", 157 }, + { "IO Capability Request Reply", 151 }, + + { "User Confirmation Request Reply", 152 }, + { "User Confirmation Request Negative Reply", 153 }, + { "User Passkey Request Reply", 154 }, + { "User Passkey Request Negative Reply", 155 }, + { "Remote OOB Data Request Reply", 156 }, + { "Write Simple Pairing Debug Mode", 157 }, { "Enhanced Flush", 158 }, - { "Unknown", 159 }, + { "Remote OOB Data Request Negative Reply", 159 }, { "Reserved", 160 }, { "Reserved", 161 }, - { "Unknown", 162 }, - { "Unknown", 163 }, + { "Send Keypress Notification", 162 }, + { "IO Capabilities Response Negative Reply", 163 }, { "Reserved", 164 }, { "Reserved", 165 }, { "Reserved", 166 }, @@ -646,8 +646,8 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_EXT_INQ }, /* Bit 0 */ { "", 0x02 }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ - { "", 0x08 }, /* Bit 3 */ - { "", 0x10 }, /* Bit 4 */ + { "", LMP_SIMPLE_PAIR }, /* Bit 3 */ + { "", LMP_ENCAPS_PDU }, /* Bit 4 */ { "", LMP_ERR_DAT_REP }, /* Bit 5 */ { "", LMP_NFLUSH_PKTS }, /* Bit 6 */ { "", 0x80 }, /* Bit 7 */ @@ -2060,6 +2060,81 @@ int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to) return 0; } +int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to) +{ + read_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SIMPLE_PAIRING_MODE; + rq.rparam = &rp; + rq.rlen = READ_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to) +{ + write_simple_pairing_mode_cp cp; + write_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_SIMPLE_PAIRING_MODE; + rq.cparam = &cp; + rq.clen = WRITE_SIMPLE_PAIRING_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to) +{ + read_local_oob_data_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_OOB_DATA; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_OOB_DATA_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(hash, rp.hash, 16); + memcpy(randomizer, rp.randomizer, 16); + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit