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 17 hci_cmd_t hci_inquiry = { 18 OPCODE(0x01, 0x01), "311" // LAP, Inquiry length, Num_responses 19 }; 20 21 hci_cmd_t hci_reset = { 22 OPCODE(0x03, 0x03), "" 23 }; 24 25 26 static hci_transport_t *hci_transport; 27 28 void hexdump(uint8_t *data, int size){ 29 int i; 30 for (i=0; i<size;i++){ 31 printf("%02X ", data[i]); 32 } 33 printf("\n"); 34 } 35 36 #if 0 37 static void *hci_daemon_thread(void *arg){ 38 printf("HCI Daemon started\n"); 39 hci_run(transport, &config); 40 return NULL; 41 } 42 #endif 43 44 void hci_init(hci_transport_t *transport, void *config){ 45 46 // reference to use transport layer implementation 47 hci_transport = transport; 48 49 // open unix socket 50 51 // wait for connections 52 53 // enter loop 54 55 // handle events 56 } 57 58 int hci_power_control(HCI_POWER_MODE power_mode){ 59 return 0; 60 } 61 62 int hci_send_cmd_packet(uint8_t *buffer, int size){ 63 return hci_transport->send_cmd_packet(buffer, size); 64 } 65 66 void hci_run(){ 67 while (1) { 68 // construct file descriptor set to wait for 69 // select 70 71 // for each ready file in FD - call handle_data 72 sleep(1); 73 } 74 } 75 76 77 void hci_create_cmd_packet(uint8_t *buffer, uint8_t *cmd_len, hci_cmd_t *cmd, ...){ 78 buffer[0] = cmd->opcode & 0xff; 79 buffer[1] = cmd->opcode >> 8; 80 int pos = 3; 81 82 va_list argptr; 83 va_start(argptr, cmd); 84 const char *format = cmd->format; 85 uint16_t word; 86 uint32_t longword; 87 uint8_t * bt_addr; 88 while (*format) { 89 switch(*format) { 90 case '1': // 8 bit value 91 case '2': // 16 bit value 92 case 'H': // hci_handle 93 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 94 buffer[pos++] = word & 0xff; 95 if (*format == '2') { 96 buffer[pos++] = word >> 8; 97 } else if (*format == 'H') { 98 // TODO 99 } 100 break; 101 case '3': 102 case '4': 103 longword = va_arg(argptr, uint32_t); 104 // longword = va_arg(argptr, int); 105 buffer[pos++] = longword; 106 buffer[pos++] = longword >> 8; 107 buffer[pos++] = longword >> 16; 108 if (*format == '4'){ 109 buffer[pos++] = longword >> 24; 110 } 111 break; 112 case 'B': // bt-addr 113 bt_addr = va_arg(argptr, uint8_t *); 114 memcpy( &buffer[pos], bt_addr, 6); 115 pos += 6; 116 break; 117 default: 118 break; 119 } 120 format++; 121 }; 122 va_end(argptr); 123 buffer[2] = pos - 3; 124 *cmd_len = pos; 125 }