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> 993b8dc03Smatthias.ringwald #include <stdarg.h> 1093b8dc03Smatthias.ringwald #include <string.h> 11*56fe0872Smatthias.ringwald #include <stdio.h> 121f504dbdSmatthias.ringwald #include "hci.h" 131f504dbdSmatthias.ringwald 1493b8dc03Smatthias.ringwald 1593b8dc03Smatthias.ringwald hci_cmd_t hci_inquiry = { 1693b8dc03Smatthias.ringwald 0x01, 0x01, "311" // LAP, Inquiry length, Num_responses 1793b8dc03Smatthias.ringwald }; 1893b8dc03Smatthias.ringwald 1993b8dc03Smatthias.ringwald hci_cmd_t hci_reset = { 2093b8dc03Smatthias.ringwald 0x03, 0x03, "" 2193b8dc03Smatthias.ringwald }; 2293b8dc03Smatthias.ringwald 2393b8dc03Smatthias.ringwald 24475c8125Smatthias.ringwald static hci_transport_t *hci_transport; 25475c8125Smatthias.ringwald 26*56fe0872Smatthias.ringwald void hexdump(uint8_t *data, int size){ 27*56fe0872Smatthias.ringwald int i; 28*56fe0872Smatthias.ringwald for (i=0; i<size;i++){ 29*56fe0872Smatthias.ringwald printf("%02X ", data[i]); 30*56fe0872Smatthias.ringwald } 31*56fe0872Smatthias.ringwald printf("\n"); 32*56fe0872Smatthias.ringwald } 33*56fe0872Smatthias.ringwald 34*56fe0872Smatthias.ringwald #if 0 35*56fe0872Smatthias.ringwald static void *hci_daemon_thread(void *arg){ 36*56fe0872Smatthias.ringwald printf("HCI Daemon started\n"); 37*56fe0872Smatthias.ringwald hci_run(transport, &config); 38*56fe0872Smatthias.ringwald return NULL; 39*56fe0872Smatthias.ringwald } 40*56fe0872Smatthias.ringwald #endif 41*56fe0872Smatthias.ringwald 42475c8125Smatthias.ringwald void hci_init(hci_transport_t *transport, void *config){ 43475c8125Smatthias.ringwald 44475c8125Smatthias.ringwald // reference to use transport layer implementation 45475c8125Smatthias.ringwald hci_transport = transport; 46475c8125Smatthias.ringwald 47475c8125Smatthias.ringwald // open unix socket 48475c8125Smatthias.ringwald 49475c8125Smatthias.ringwald // wait for connections 50475c8125Smatthias.ringwald 51475c8125Smatthias.ringwald // enter loop 52475c8125Smatthias.ringwald 53475c8125Smatthias.ringwald // handle events 54475c8125Smatthias.ringwald } 55475c8125Smatthias.ringwald 56475c8125Smatthias.ringwald int hci_power_control(HCI_POWER_MODE power_mode){ 57475c8125Smatthias.ringwald return 0; 58475c8125Smatthias.ringwald } 59475c8125Smatthias.ringwald 60*56fe0872Smatthias.ringwald int hci_send_cmd_packet(uint8_t *buffer, int size){ 61475c8125Smatthias.ringwald return hci_transport->send_cmd_packet(buffer, size); 62475c8125Smatthias.ringwald } 63475c8125Smatthias.ringwald 64475c8125Smatthias.ringwald void hci_run(){ 65475c8125Smatthias.ringwald while (1) { 66475c8125Smatthias.ringwald // construct file descriptor set to wait for 67475c8125Smatthias.ringwald // select 68475c8125Smatthias.ringwald 69475c8125Smatthias.ringwald // for each ready file in FD - call handle_data 70475c8125Smatthias.ringwald sleep(1); 71475c8125Smatthias.ringwald } 721f504dbdSmatthias.ringwald } 7393b8dc03Smatthias.ringwald 7493b8dc03Smatthias.ringwald 7593b8dc03Smatthias.ringwald void hci_create_cmd_packet(uint8_t *buffer, uint8_t *cmd_len, hci_cmd_t *cmd, ...){ 7693b8dc03Smatthias.ringwald buffer[0] = cmd->ocf; 7793b8dc03Smatthias.ringwald buffer[1] = cmd->ocf >> 8 | cmd->ogf << 2; 7893b8dc03Smatthias.ringwald int pos = 3; 7993b8dc03Smatthias.ringwald 8093b8dc03Smatthias.ringwald va_list argptr; 8193b8dc03Smatthias.ringwald va_start(argptr, cmd); 8293b8dc03Smatthias.ringwald const char *format = cmd->format; 8393b8dc03Smatthias.ringwald uint16_t word; 8493b8dc03Smatthias.ringwald uint32_t longword; 8593b8dc03Smatthias.ringwald uint8_t * bt_addr; 8693b8dc03Smatthias.ringwald while (*format) { 8793b8dc03Smatthias.ringwald switch(*format) { 8893b8dc03Smatthias.ringwald case '1': // 8 bit value 8993b8dc03Smatthias.ringwald case '2': // 16 bit value 9093b8dc03Smatthias.ringwald case 'H': // hci_handle 9193b8dc03Smatthias.ringwald word = va_arg(argptr, int); // minimum c parameter width is int 9293b8dc03Smatthias.ringwald buffer[pos++] = word & 0xff; 9393b8dc03Smatthias.ringwald if (*format == '2') { 9493b8dc03Smatthias.ringwald buffer[pos++] = word >> 8; 9593b8dc03Smatthias.ringwald } else if (*format == 'H') { 9693b8dc03Smatthias.ringwald 9793b8dc03Smatthias.ringwald } 9893b8dc03Smatthias.ringwald break; 9993b8dc03Smatthias.ringwald case '3': 10093b8dc03Smatthias.ringwald case '4': 10193b8dc03Smatthias.ringwald longword = va_arg(argptr, uint32_t); 10293b8dc03Smatthias.ringwald // longword = va_arg(argptr, int); 10393b8dc03Smatthias.ringwald buffer[pos++] = longword; 10493b8dc03Smatthias.ringwald buffer[pos++] = longword >> 8; 10593b8dc03Smatthias.ringwald buffer[pos++] = longword >> 16; 10693b8dc03Smatthias.ringwald if (*format == '4'){ 10793b8dc03Smatthias.ringwald buffer[pos++] = longword >> 24; 10893b8dc03Smatthias.ringwald } 10993b8dc03Smatthias.ringwald break; 11093b8dc03Smatthias.ringwald case 'B': // bt-addr 11193b8dc03Smatthias.ringwald bt_addr = va_arg(argptr, uint8_t *); 11293b8dc03Smatthias.ringwald memcpy( &buffer[pos], bt_addr, 6); 11393b8dc03Smatthias.ringwald pos += 6; 11493b8dc03Smatthias.ringwald break; 11593b8dc03Smatthias.ringwald default: 11693b8dc03Smatthias.ringwald break; 11793b8dc03Smatthias.ringwald } 11893b8dc03Smatthias.ringwald format++; 11993b8dc03Smatthias.ringwald }; 12093b8dc03Smatthias.ringwald va_end(argptr); 12193b8dc03Smatthias.ringwald buffer[2] = pos - 3; 12293b8dc03Smatthias.ringwald *cmd_len = pos; 12393b8dc03Smatthias.ringwald }