xref: /btstack/src/hci.c (revision 0a974e0c4482b3feeb23227e3c157e6c9aec941f)
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 }