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