1 /* 2 * hci.c 3 * 4 * Created by Matthias Ringwald on 4/29/09. 5 * 6 */ 7 8 #include <unistd.h> 9 #include <stdarg.h> 10 #include <string.h> 11 #include <stdio.h> 12 #include "hci.h" 13 14 // calculate combined ogf/ocf value 15 #define OPCODE(ogf, ocf) (ocf | ogf << 10) 16 #define OGF_LINK_CONTROL 0x01 17 #define OGF_CONTROLLER_BASEBAND 0x03 18 19 hci_cmd_t hci_inquiry = { 20 OPCODE(OGF_LINK_CONTROL, 0x01), "311" 21 // LAP, Inquiry length, Num_responses 22 }; 23 24 hci_cmd_t hci_link_key_request_negative_reply = { 25 OPCODE(OGF_LINK_CONTROL, 0x0c), "B" 26 }; 27 28 hci_cmd_t hci_pin_code_request_reply = { 29 OPCODE(OGF_LINK_CONTROL, 0x0d), "B1P" 30 // BD_ADDR, pin length, PIN: c-string 31 }; 32 33 hci_cmd_t hci_reset = { 34 OPCODE(OGF_CONTROLLER_BASEBAND, 0x03), "" 35 }; 36 37 hci_cmd_t hci_create_connection = { 38 OPCODE(OGF_LINK_CONTROL, 0x05), "B21121" 39 // BD_ADDR, Packet_Type, Page_Scan_Repetition_Mode, Reserved, Clock_Offset, Allow_Role_Switch 40 }; 41 42 hci_cmd_t hci_write_page_timeout = { 43 OPCODE(OGF_CONTROLLER_BASEBAND, 0x18), "2" 44 // Page_Timeout * 0.625 ms 45 }; 46 47 hci_cmd_t hci_write_authentication_enable = { 48 OPCODE(OGF_CONTROLLER_BASEBAND, 0x20), "1" 49 // Authentication_Enable 50 }; 51 52 hci_cmd_t hci_host_buffer_size = { 53 OPCODE(OGF_CONTROLLER_BASEBAND, 0x33), "2122" 54 // Host_ACL_Data_Packet_Length:, Host_Synchronous_Data_Packet_Length:, Host_Total_Num_ACL_Data_Packets:, Host_Total_Num_Synchronous_Data_Packets: 55 }; 56 57 58 // the stack is here 59 static hci_stack_t hci_stack; 60 61 62 void bt_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){ 63 buffer[pos] = value & 0xff; 64 buffer[pos+1] = value >> 8; 65 } 66 67 void bt_flip_addr(bd_addr_t dest, bd_addr_t src){ 68 dest[0] = src[5]; 69 dest[1] = src[4]; 70 dest[2] = src[3]; 71 dest[3] = src[2]; 72 dest[4] = src[1]; 73 dest[5] = src[0]; 74 } 75 76 void hexdump(uint8_t *data, int size){ 77 int i; 78 for (i=0; i<size;i++){ 79 printf("%02X ", data[i]); 80 } 81 printf("\n"); 82 } 83 84 #if 0 85 static void *hci_daemon_thread(void *arg){ 86 printf("HCI Daemon started\n"); 87 hci_run(transport, &config); 88 return NULL; 89 } 90 #endif 91 92 /** 93 * Handler called by HCI transport 94 */ 95 static void dummy_handler(uint8_t *packet, int size){ 96 } 97 98 static void acl_handler(uint8_t *packet, int size){ 99 hci_stack.acl_packet_handler(packet, size); 100 } 101 102 static void event_handler(uint8_t *packet, int size){ 103 bd_addr_t addr; 104 105 if ( COMMAND_COMPLETE_EVENT(packet, hci_reset) ) { 106 // reset done, write page timeout 107 hci_send_cmd(&hci_write_page_timeout, 0x6000); // ca. 15 sec 108 return; 109 } 110 111 if ( COMMAND_COMPLETE_EVENT(packet, hci_write_page_timeout) ) { 112 uint8_t micro_packet = 100; 113 hci_stack.event_packet_handler(µ_packet, 1); 114 return; 115 } 116 117 // link key request 118 if (packet[0] == 0x17){ 119 bt_flip_addr(addr, &packet[2]); 120 hci_send_cmd(&hci_link_key_request_negative_reply, &addr); 121 return; 122 } 123 124 // pin code request 125 if (packet[0] == 0x16){ 126 bt_flip_addr(addr, &packet[2]); 127 hci_send_cmd(&hci_pin_code_request_reply, &addr, 4, "1234"); 128 } 129 130 hci_stack.event_packet_handler(packet, size); 131 } 132 133 /** Register L2CAP handlers */ 134 void hci_register_event_packet_handler(void (*handler)(uint8_t *packet, int size)){ 135 hci_stack.event_packet_handler = handler; 136 } 137 void hci_register_acl_packet_handler (void (*handler)(uint8_t *packet, int size)){ 138 hci_stack.acl_packet_handler = handler; 139 } 140 141 void hci_init(hci_transport_t *transport, void *config){ 142 143 // reference to use transport layer implementation 144 hci_stack.hci_transport = transport; 145 146 // empty cmd buffer 147 hci_stack.hci_cmd_buffer = malloc(3+255); 148 149 // higher level handler 150 hci_stack.event_packet_handler = dummy_handler; 151 hci_stack.acl_packet_handler = dummy_handler; 152 153 // register packet handlers with transport 154 transport->register_event_packet_handler( event_handler); 155 transport->register_acl_packet_handler( acl_handler); 156 157 // open low-level device 158 transport->open(config); 159 160 // open unix socket 161 162 // wait for connections 163 164 // enter loop 165 166 // handle events 167 } 168 169 int hci_power_control(HCI_POWER_MODE power_mode){ 170 return 0; 171 } 172 173 void hci_run(){ 174 175 // send hci reset 176 hci_send_cmd(&hci_reset); 177 178 #if 0 179 while (1) { 180 // construct file descriptor set to wait for 181 // select 182 183 // for each ready file in FD - call handle_data 184 sleep(1); 185 } 186 #endif 187 } 188 189 190 191 192 193 int hci_send_acl_packet(uint8_t *packet, int size){ 194 return hci_stack.hci_transport->send_acl_packet(packet, size); 195 } 196 197 int hci_send_cmd(hci_cmd_t *cmd, ...){ 198 uint8_t * hci_cmd_buffer = hci_stack.hci_cmd_buffer; 199 hci_cmd_buffer[0] = cmd->opcode & 0xff; 200 hci_cmd_buffer[1] = cmd->opcode >> 8; 201 int pos = 3; 202 203 va_list argptr; 204 va_start(argptr, cmd); 205 const char *format = cmd->format; 206 uint16_t word; 207 uint32_t longword; 208 uint8_t * ptr; 209 while (*format) { 210 switch(*format) { 211 case '1': // 8 bit value 212 case '2': // 16 bit value 213 case 'H': // hci_handle 214 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 215 hci_cmd_buffer[pos++] = word & 0xff; 216 if (*format == '2') { 217 hci_cmd_buffer[pos++] = word >> 8; 218 } else if (*format == 'H') { 219 // TODO 220 } 221 break; 222 case '3': 223 case '4': 224 longword = va_arg(argptr, uint32_t); 225 // longword = va_arg(argptr, int); 226 hci_cmd_buffer[pos++] = longword; 227 hci_cmd_buffer[pos++] = longword >> 8; 228 hci_cmd_buffer[pos++] = longword >> 16; 229 if (*format == '4'){ 230 hci_cmd_buffer[pos++] = longword >> 24; 231 } 232 break; 233 case 'B': // bt-addr 234 ptr = va_arg(argptr, uint8_t *); 235 hci_cmd_buffer[pos++] = ptr[5]; 236 hci_cmd_buffer[pos++] = ptr[4]; 237 hci_cmd_buffer[pos++] = ptr[3]; 238 hci_cmd_buffer[pos++] = ptr[2]; 239 hci_cmd_buffer[pos++] = ptr[1]; 240 hci_cmd_buffer[pos++] = ptr[0]; 241 break; 242 case 'P': // c string passed as pascal string with leading 1-byte len 243 ptr = va_arg(argptr, uint8_t *); 244 memcpy(&hci_cmd_buffer[pos], ptr, 16); 245 pos += 16; 246 break; 247 default: 248 break; 249 } 250 format++; 251 }; 252 va_end(argptr); 253 hci_cmd_buffer[2] = pos - 3; 254 // send packet 255 return hci_stack.hci_transport->send_cmd_packet(hci_cmd_buffer, pos); 256 }