1 /* 2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist 4 * 5 * All rights reserved. Distributed under the terms of the MIT License. 6 * 7 */ 8 9 10 #include <bluetooth/bluetooth.h> 11 #include <bluetooth/HCI/btHCI_command.h> 12 13 #include <malloc.h> 14 #include <string.h> 15 16 #include "CommandManager.h" 17 18 19 inline void* buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize, size_t* outsize) 20 { 21 struct hci_command_header* header; 22 23 #ifdef BT_IOCTLS_PASS_SIZE 24 header = (struct hci_command_header*) malloc(psize + sizeof(struct hci_command_header)); 25 *outsize = psize + sizeof(struct hci_command_header); 26 #else 27 size_t* size = (size_t*)malloc(psize + sizeof(struct hci_command_header) + sizeof(size_t)); 28 *outsize = psize + sizeof(struct hci_command_header) + sizeof(size_t); 29 30 *size = psize + sizeof(struct hci_command_header); 31 header = (struct hci_command_header*) (((uint8*)size)+4); 32 #endif 33 34 35 if (header != NULL) { 36 37 header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf)); 38 header->clen = psize; 39 40 if (param != NULL && psize != 0) { 41 *param = ((uint8*)header) + sizeof(struct hci_command_header); 42 } 43 } 44 #ifdef BT_IOCTLS_PASS_SIZE 45 return header; 46 #else 47 return (void*)size; 48 #endif 49 } 50 51 52 #if 0 53 #pragma mark - CONTROL BASEBAND - 54 #endif 55 56 57 void* buildReset(size_t* outsize) 58 { 59 return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET, NULL, 0, outsize); 60 } 61 62 63 void* buildReadLocalName(size_t* outsize) 64 { 65 return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME, NULL, 0, outsize); 66 } 67 68 69 void* buildWriteScan(uint8 scanmode, size_t* outsize) 70 { 71 struct hci_write_scan_enable* param; 72 void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE, (void**) ¶m, sizeof(struct hci_write_scan_enable), outsize); 73 74 75 if (command != NULL) { 76 param->scan = scanmode; 77 } 78 79 return command; 80 81 } 82 83 84 void* buildAuthEnable(uint8 auth, size_t* outsize) 85 { 86 struct hci_write_authentication_enable* param; 87 void* command = buildCommand(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE, (void**) ¶m, sizeof(struct hci_write_authentication_enable), outsize); 88 89 90 if (command != NULL) { 91 param->authentication = auth; 92 } 93 94 return command; 95 96 } 97 98 99 #if 0 100 #pragma mark - LINK CONTROL - 101 #endif 102 103 104 void* buildCreateConnection(bdaddr_t bdaddr) 105 { 106 /* 107 cm4.size = sizeof(struct hci_command_header)+sizeof(struct hci_cp_create_conn); 108 cm4.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CONTROL, OCF_CREATE_CONN)); 109 cm4.body.bdaddr.b[0] = 0x92; 110 cm4.body.bdaddr.b[1] = 0xd3; 111 cm4.body.bdaddr.b[2] = 0xaf; 112 cm4.body.bdaddr.b[3] = 0xd9; 113 cm4.body.bdaddr.b[4] = 0x0a; 114 cm4.body.bdaddr.b[5] = 0x00; 115 cm4.body.pkt_type = 0xFFFF; 116 cm4.body.pscan_rep_mode = 1; 117 cm4.body.pscan_mode = 0; 118 cm4.body.clock_offset = 0xc7; 119 cm4.body.role_switch = 1; 120 cm4.header.clen = 13; 121 ioctl(fd1, ISSUE_BT_COMMAND, &cm4, sizeof(cm4)); 122 */ 123 124 return NULL; 125 } 126 127 128 void* buildRemoteNameRequest(bdaddr_t bdaddr,uint8 pscan_rep_mode, uint16 clock_offset, size_t* outsize) 129 { 130 131 struct hci_remote_name_request* param; 132 void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST, (void**) ¶m, sizeof(struct hci_remote_name_request), outsize); 133 134 if (command != NULL) { 135 param->bdaddr = bdaddr; 136 param->pscan_rep_mode = pscan_rep_mode; 137 param->clock_offset = clock_offset; 138 } 139 140 return command; 141 } 142 143 144 void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize) 145 { 146 147 struct hci_cp_inquiry* param; 148 void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY, (void**) ¶m, sizeof(struct hci_cp_inquiry), outsize); 149 150 if (command != NULL) { 151 152 param->lap[2] = (lap >> 16) & 0xFF; 153 param->lap[1] = (lap >> 8) & 0xFF; 154 param->lap[0] = (lap >> 0) & 0xFF; 155 param->length = length; 156 param->num_rsp = num_rsp; 157 } 158 159 return command; 160 } 161 162 163 void* buildInquiryCancel(size_t* outsize) 164 { 165 166 return buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL, NULL, 0, outsize); 167 168 } 169 170 171 void* buildPinCodeRequestReply(bdaddr_t bdaddr, uint8 length, char pincode[16], size_t* outsize) 172 { 173 174 struct hci_cp_pin_code_reply* param; 175 176 if (length > HCI_PIN_SIZE) // PinCode cannot be longer than 16 177 return NULL; 178 179 void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY, (void**) ¶m, sizeof(struct hci_cp_pin_code_reply), outsize); 180 181 if (command != NULL) { 182 183 param->bdaddr = bdaddr; 184 param->pin_len = length; 185 memcpy(¶m->pin_code, pincode, length); 186 187 } 188 189 return command; 190 } 191 192 193 void* buildPinCodeRequestNegativeReply(bdaddr_t bdaddr, size_t* outsize) 194 { 195 196 struct hci_cp_pin_code_neg_reply* param; 197 198 void* command = buildCommand(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY, 199 (void**) ¶m, sizeof(struct hci_cp_pin_code_neg_reply), outsize); 200 201 if (command != NULL) { 202 203 param->bdaddr = bdaddr; 204 205 } 206 207 return command; 208 } 209 210 211 void* buildAcceptConnectionRequest(bdaddr_t bdaddr, uint8 role, size_t* outsize) 212 { 213 struct hci_cp_accept_conn_req* param; 214 215 void* command = buildCommand(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ, 216 (void**) ¶m, sizeof(struct hci_cp_accept_conn_req), outsize); 217 218 if (command != NULL) { 219 param->bdaddr = bdaddr; 220 param->role = role; 221 } 222 223 return command; 224 } 225 226 227 void* buildRejectConnectionRequest(bdaddr_t bdaddr, size_t* outsize) 228 { 229 struct hci_cp_reject_conn_req* param; 230 231 void *command = buildCommand(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ, 232 (void**) ¶m, sizeof(struct hci_cp_reject_conn_req), outsize); 233 234 if (command != NULL) { 235 param->bdaddr = bdaddr; 236 } 237 238 return command; 239 } 240 241 242 #if 0 243 #pragma mark - INFORMATIONAL_PARAM - 244 #endif 245 246 247 void* buildReadBufferSize(size_t* outsize) 248 { 249 return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE, NULL, 0, outsize); 250 } 251 252 253 void* buildReadBdAddr(size_t* outsize) 254 { 255 return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR, NULL, 0, outsize); 256 } 257 258 259 260 261