11f504dbdSmatthias.ringwald /* 21f504dbdSmatthias.ringwald * hci.c 31f504dbdSmatthias.ringwald * 41f504dbdSmatthias.ringwald * Created by Matthias Ringwald on 4/29/09. 51f504dbdSmatthias.ringwald * 61f504dbdSmatthias.ringwald */ 71f504dbdSmatthias.ringwald 8475c8125Smatthias.ringwald #include <unistd.h> 9*93b8dc03Smatthias.ringwald #include <stdarg.h> 10*93b8dc03Smatthias.ringwald #include <string.h> 111f504dbdSmatthias.ringwald #include "hci.h" 121f504dbdSmatthias.ringwald 13*93b8dc03Smatthias.ringwald 14*93b8dc03Smatthias.ringwald hci_cmd_t hci_inquiry = { 15*93b8dc03Smatthias.ringwald 0x01, 0x01, "311" // LAP, Inquiry length, Num_responses 16*93b8dc03Smatthias.ringwald }; 17*93b8dc03Smatthias.ringwald 18*93b8dc03Smatthias.ringwald hci_cmd_t hci_reset = { 19*93b8dc03Smatthias.ringwald 0x03, 0x03, "" 20*93b8dc03Smatthias.ringwald }; 21*93b8dc03Smatthias.ringwald 22*93b8dc03Smatthias.ringwald 23475c8125Smatthias.ringwald static hci_transport_t *hci_transport; 24475c8125Smatthias.ringwald 25475c8125Smatthias.ringwald void hci_init(hci_transport_t *transport, void *config){ 26475c8125Smatthias.ringwald 27475c8125Smatthias.ringwald // reference to use transport layer implementation 28475c8125Smatthias.ringwald hci_transport = transport; 29475c8125Smatthias.ringwald 30475c8125Smatthias.ringwald // open unix socket 31475c8125Smatthias.ringwald 32475c8125Smatthias.ringwald // wait for connections 33475c8125Smatthias.ringwald 34475c8125Smatthias.ringwald // enter loop 35475c8125Smatthias.ringwald 36475c8125Smatthias.ringwald // handle events 37475c8125Smatthias.ringwald } 38475c8125Smatthias.ringwald 39475c8125Smatthias.ringwald int hci_power_control(HCI_POWER_MODE power_mode){ 40475c8125Smatthias.ringwald return 0; 41475c8125Smatthias.ringwald } 42475c8125Smatthias.ringwald 43*93b8dc03Smatthias.ringwald int hci_send_cmd(uint8_t *buffer, int size){ 44475c8125Smatthias.ringwald return hci_transport->send_cmd_packet(buffer, size); 45475c8125Smatthias.ringwald } 46475c8125Smatthias.ringwald 47475c8125Smatthias.ringwald void hci_run(){ 48475c8125Smatthias.ringwald while (1) { 49475c8125Smatthias.ringwald // construct file descriptor set to wait for 50475c8125Smatthias.ringwald // select 51475c8125Smatthias.ringwald 52475c8125Smatthias.ringwald // for each ready file in FD - call handle_data 53475c8125Smatthias.ringwald sleep(1); 54475c8125Smatthias.ringwald } 551f504dbdSmatthias.ringwald } 56*93b8dc03Smatthias.ringwald 57*93b8dc03Smatthias.ringwald 58*93b8dc03Smatthias.ringwald void hci_create_cmd_packet(uint8_t *buffer, uint8_t *cmd_len, hci_cmd_t *cmd, ...){ 59*93b8dc03Smatthias.ringwald buffer[0] = cmd->ocf; 60*93b8dc03Smatthias.ringwald buffer[1] = cmd->ocf >> 8 | cmd->ogf << 2; 61*93b8dc03Smatthias.ringwald int pos = 3; 62*93b8dc03Smatthias.ringwald 63*93b8dc03Smatthias.ringwald va_list argptr; 64*93b8dc03Smatthias.ringwald va_start(argptr, cmd); 65*93b8dc03Smatthias.ringwald const char *format = cmd->format; 66*93b8dc03Smatthias.ringwald uint16_t word; 67*93b8dc03Smatthias.ringwald uint32_t longword; 68*93b8dc03Smatthias.ringwald uint8_t * bt_addr; 69*93b8dc03Smatthias.ringwald while (*format) { 70*93b8dc03Smatthias.ringwald switch(*format) { 71*93b8dc03Smatthias.ringwald case '1': // 8 bit value 72*93b8dc03Smatthias.ringwald case '2': // 16 bit value 73*93b8dc03Smatthias.ringwald case 'H': // hci_handle 74*93b8dc03Smatthias.ringwald word = va_arg(argptr, int); // minimum c parameter width is int 75*93b8dc03Smatthias.ringwald buffer[pos++] = word & 0xff; 76*93b8dc03Smatthias.ringwald if (*format == '2') { 77*93b8dc03Smatthias.ringwald buffer[pos++] = word >> 8; 78*93b8dc03Smatthias.ringwald } else if (*format == 'H') { 79*93b8dc03Smatthias.ringwald 80*93b8dc03Smatthias.ringwald } 81*93b8dc03Smatthias.ringwald break; 82*93b8dc03Smatthias.ringwald case '3': 83*93b8dc03Smatthias.ringwald case '4': 84*93b8dc03Smatthias.ringwald longword = va_arg(argptr, uint32_t); 85*93b8dc03Smatthias.ringwald // longword = va_arg(argptr, int); 86*93b8dc03Smatthias.ringwald buffer[pos++] = longword; 87*93b8dc03Smatthias.ringwald buffer[pos++] = longword >> 8; 88*93b8dc03Smatthias.ringwald buffer[pos++] = longword >> 16; 89*93b8dc03Smatthias.ringwald if (*format == '4'){ 90*93b8dc03Smatthias.ringwald buffer[pos++] = longword >> 24; 91*93b8dc03Smatthias.ringwald } 92*93b8dc03Smatthias.ringwald break; 93*93b8dc03Smatthias.ringwald case 'B': // bt-addr 94*93b8dc03Smatthias.ringwald bt_addr = va_arg(argptr, uint8_t *); 95*93b8dc03Smatthias.ringwald memcpy( &buffer[pos], bt_addr, 6); 96*93b8dc03Smatthias.ringwald pos += 6; 97*93b8dc03Smatthias.ringwald break; 98*93b8dc03Smatthias.ringwald default: 99*93b8dc03Smatthias.ringwald break; 100*93b8dc03Smatthias.ringwald } 101*93b8dc03Smatthias.ringwald format++; 102*93b8dc03Smatthias.ringwald }; 103*93b8dc03Smatthias.ringwald va_end(argptr); 104*93b8dc03Smatthias.ringwald buffer[2] = pos - 3; 105*93b8dc03Smatthias.ringwald *cmd_len = pos; 106*93b8dc03Smatthias.ringwald }