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 #include "hci_dump.h" 14 15 // the stack is here 16 static hci_stack_t hci_stack; 17 18 /** 19 * get link for given address 20 * 21 * @return connection OR NULL, if not found 22 */ 23 static hci_connection_t *link_for_addr(bd_addr_t addr){ 24 return NULL; 25 } 26 27 /** 28 * Dummy handler called by HCI 29 */ 30 static void dummy_handler(uint8_t *packet, uint16_t size){ 31 } 32 33 /** 34 * Dummy control handler 35 */ 36 static int null_control_function(void *config){ 37 return 0; 38 } 39 static const char * null_control_name(void *config){ 40 return "Hardware unknown"; 41 } 42 static bt_control_t null_control = { 43 null_control_function, 44 null_control_function, 45 null_control_function, 46 null_control_name 47 }; 48 49 static void acl_handler(uint8_t *packet, int size){ 50 hci_stack.acl_packet_handler(packet, size); 51 52 // execute main loop 53 hci_run(); 54 } 55 56 static void event_handler(uint8_t *packet, int size){ 57 bd_addr_t addr; 58 59 // Get Num_HCI_Command_Packets 60 if (packet[0] == HCI_EVENT_COMMAND_COMPLETE || 61 packet[0] == HCI_EVENT_COMMAND_STATUS){ 62 hci_stack.num_cmd_packets = packet[2]; 63 } 64 65 // handle BT initialization 66 if (hci_stack.state == HCI_STATE_INITIALIZING){ 67 // handle H4 synchronization loss on restart 68 // if (hci_stack.substate == 1 && packet[0] == HCI_EVENT_HARDWARE_ERROR){ 69 // hci_stack.substate = 0; 70 // } 71 // handle normal init sequence 72 if (hci_stack.substate % 2){ 73 // odd: waiting for event 74 if (packet[0] == HCI_EVENT_COMMAND_COMPLETE){ 75 hci_stack.substate++; 76 } 77 } 78 } 79 80 // link key request 81 if (packet[0] == HCI_EVENT_LINK_KEY_REQUEST){ 82 bt_flip_addr(addr, &packet[2]); 83 hci_send_cmd(&hci_link_key_request_negative_reply, &addr); 84 return; 85 } 86 87 // pin code request 88 if (packet[0] == HCI_EVENT_PIN_CODE_REQUEST){ 89 bt_flip_addr(addr, &packet[2]); 90 hci_send_cmd(&hci_pin_code_request_reply, &addr, 4, "1234"); 91 } 92 93 hci_stack.event_packet_handler(packet, size); 94 95 // execute main loop 96 hci_run(); 97 } 98 99 /** Register L2CAP handlers */ 100 void hci_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size)){ 101 hci_stack.event_packet_handler = handler; 102 } 103 void hci_register_acl_packet_handler (void (*handler)(uint8_t *packet, uint16_t size)){ 104 hci_stack.acl_packet_handler = handler; 105 } 106 107 void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){ 108 109 // reference to use transport layer implementation 110 hci_stack.hci_transport = transport; 111 112 // references to used control implementation 113 if (control) { 114 hci_stack.control = control; 115 } else { 116 hci_stack.control = &null_control; 117 } 118 119 // reference to used config 120 hci_stack.config = config; 121 122 // empty cmd buffer 123 hci_stack.hci_cmd_buffer = malloc(3+255); 124 125 // higher level handler 126 hci_stack.event_packet_handler = dummy_handler; 127 hci_stack.acl_packet_handler = dummy_handler; 128 129 // register packet handlers with transport 130 transport->register_event_packet_handler( event_handler); 131 transport->register_acl_packet_handler( acl_handler); 132 } 133 134 int hci_power_control(HCI_POWER_MODE power_mode){ 135 if (power_mode == HCI_POWER_ON) { 136 137 // set up state machine 138 hci_stack.num_cmd_packets = 1; // assume that one cmd can be sent 139 hci_stack.state = HCI_STATE_INITIALIZING; 140 hci_stack.substate = 0; 141 142 // power on 143 hci_stack.control->on(hci_stack.config); 144 145 // open low-level device 146 hci_stack.hci_transport->open(hci_stack.config); 147 148 } else if (power_mode == HCI_POWER_OFF){ 149 150 // close low-level device 151 hci_stack.hci_transport->close(hci_stack.config); 152 153 // power off 154 hci_stack.control->off(hci_stack.config); 155 } 156 157 // trigger next/first action 158 hci_run(); 159 160 return 0; 161 } 162 163 uint32_t hci_run(){ 164 uint8_t micro_packet; 165 switch (hci_stack.state){ 166 case HCI_STATE_INITIALIZING: 167 if (hci_stack.substate % 2) { 168 // odd: waiting for command completion 169 return 0; 170 } 171 if (hci_stack.num_cmd_packets == 0) { 172 // cannot send command yet 173 return 0; 174 } 175 switch (hci_stack.substate/2){ 176 case 0: 177 hci_send_cmd(&hci_reset); 178 break; 179 case 1: 180 hci_send_cmd(&hci_read_bd_addr); 181 break; 182 case 2: 183 // ca. 15 sec 184 hci_send_cmd(&hci_write_page_timeout, 0x6000); 185 break; 186 case 3: 187 hci_send_cmd(&hci_write_scan_enable, 3); // 3 inq scan + page scan 188 break; 189 case 4: 190 // done. 191 hci_stack.state = HCI_STATE_WORKING; 192 micro_packet = HCI_EVENT_BTSTACK_WORKING; 193 hci_stack.event_packet_handler(µ_packet, 1); 194 break; 195 default: 196 break; 197 } 198 hci_stack.substate++; 199 break; 200 default: 201 break; 202 } 203 204 // don't check for timetous yet 205 return 0; 206 } 207 208 209 int hci_send_acl_packet(uint8_t *packet, int size){ 210 return hci_stack.hci_transport->send_acl_packet(packet, size); 211 } 212 213 int hci_send_cmd_packet(uint8_t *packet, int size){ 214 if (READ_CMD_OGF(packet) != OGF_BTSTACK) { 215 hci_stack.num_cmd_packets--; 216 return hci_stack.hci_transport->send_cmd_packet(packet, size); 217 } 218 219 hci_dump_packet( HCI_COMMAND_DATA_PACKET, 1, packet, size); 220 221 // BTstack internal commands 222 uint8_t event[3]; 223 switch (READ_CMD_OCF(packet)){ 224 case HCI_BTSTACK_GET_STATE: 225 event[0] = HCI_EVENT_BTSTACK_STATE; 226 event[1] = 1; 227 event[2] = hci_stack.state; 228 hci_dump_packet( HCI_EVENT_PACKET, 0, event, 3); 229 hci_stack.event_packet_handler(event, 3); 230 break; 231 default: 232 // TODO log into hci dump as vendor specific "event" 233 printf("Error: command %u not implemented\n:", READ_CMD_OCF(packet)); 234 break; 235 } 236 return 0; 237 } 238 239 /** 240 * pre: numcmds >= 0 - it's allowed to send a command to the controller 241 */ 242 int hci_send_cmd(hci_cmd_t *cmd, ...){ 243 va_list argptr; 244 va_start(argptr, cmd); 245 uint8_t * hci_cmd_buffer = hci_stack.hci_cmd_buffer; 246 uint16_t size = hci_create_cmd_internal(hci_stack.hci_cmd_buffer, cmd, argptr); 247 va_end(argptr); 248 return hci_send_cmd_packet(hci_cmd_buffer, size); 249 }