]> git.karo-electronics.de Git - oswald.git/blob - metawatch/bt_hci.c
Sanity check for enabled BT
[oswald.git] / metawatch / bt_hci.c
1 #include <msp430.h>
2 #include <msp430xgeneric.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <string.h>
6
7 #include "mw_main.h"
8
9 #include "mw_uart.h"
10 #include "mw_bt.h"
11 #include "bt_hci.h"
12 #include "bt_l2cap.h"
13
14
15 static uint8_t local_bdaddr[6];
16
17 uint8_t *bt_hci_get_local_bdaddr(void)
18 {
19         return local_bdaddr;
20 }
21
22 static void bt_print_bd_addr(uint8_t *bd_addr)
23 {
24 #if defined MW_DEVBOARD_V2
25         int i;
26         char nums[4];
27
28         for (i=5; i>=0; i--) {
29                 snprintf(nums, 4, "%02x", bd_addr[i]);
30                 debug_uart_tx(nums);
31                 if (i>0)
32                         debug_uart_tx_char(':');
33         }
34 #endif
35 }
36
37 void bt_hci_process_acl_packet(unsigned char *packet)
38 {
39 #if defined MW_DEVBOARD_V2
40         char tstr[32];
41 #endif
42         uint16_t dlen;
43         uint16_t handle;
44         L2CAP_PB_FLAG PB;
45         L2CAP_BC_FLAG BC;
46         uint16_t channel;
47         uint16_t mlen;
48
49 //      debug_uart_tx("ACL packet, ");
50         handle = packet[0] | ((packet[1] & 0x0f) << 8);
51 //      snprintf(tstr, 32, "handle 0x%04x ", handle);
52 //      debug_uart_tx(tstr);
53         PB = (packet[1] >> 4) & 0x03;
54         BC = (packet[1] >> 6) & 0x03;
55 //      snprintf(tstr, 32, "PB 0x%02x BC 0x%02x ", PB, BC);
56 //      debug_uart_tx(tstr);
57
58         dlen = packet[2] | ((uint16_t)packet[3] << 8);
59 //      snprintf(tstr, 32, "len 0x%04x \n", dlen);
60 //      debug_uart_tx(tstr);
61 //      debug_dump_hex(dlen+4, packet);
62
63         channel = packet[4+2] | (packet[4+3] << 8);
64         mlen = packet[4] | (packet[4+1] << 8);
65         switch (channel) {
66                 case L2CAP_CID_SIGNALING:
67                         bt_l2cap_proc_signalling(handle, (packet+8), mlen);
68                         break;
69                 case L2CAP_CID_CONNECTIONLESS_CHANNEL:
70                         break;
71                 case L2CAP_CID_ATTRIBUTE_PROTOCOL:
72                         break;
73                 case L2CAP_CID_SIGNALING_LE:
74                         break;
75                 case L2CAP_CID_SECURITY_MANAGER_PROTOCOL:
76                         break;
77                 default:
78                         if (channel > 0x3f) {
79                                 // just for sure, add a 0 as string delimiter
80                                 packet[mlen+8] = 0x00;
81                                 bt_l2cap_proc_dyn_channel(channel, handle, (packet+8), mlen);
82                         } else {
83 #if defined MW_DEVBOARD_V2
84                                 snprintf(tstr, 32, "L2CAP unhandled CID 0x%04x\n", channel);
85                                 debug_uart_tx(tstr);
86 #endif
87                         }
88                         break;
89         }
90 }
91
92 void bt_hci_process_event_packet(unsigned char *packet)
93 {
94 #if defined MW_DEVBOARD_V2
95         char tstr[32];
96 #endif
97         int i;
98         // uint8_t bd_addr[6];
99         uint32_t dev_type;
100
101 //      debug_uart_tx("Event packet, ");
102 //      snprintf(tstr, 32, "evt 0x%02x: ", packet[0]);
103 //      debug_uart_tx(tstr);
104
105         switch (packet[0]) {
106                 case HCI_EVENT_INQUIRY_COMPLETE:
107                         debug_uart_tx("inq complete\n");
108                         break;
109                 case HCI_EVENT_INQUIRY_RESULT:
110                         debug_uart_tx("inq result\n");
111                         break;
112                 case HCI_EVENT_CONNECTION_COMPLETE:
113                         debug_uart_tx("con complete from ");
114 #if defined MW_DEVBOARD_V2
115                         bt_print_bd_addr((packet+5));
116                         snprintf(tstr, 32, " status 0x%02x handle 0x%02x", packet[2], packet[3]);
117                         debug_uart_tx(tstr);
118                         snprintf(tstr, 32, " type 0x%02x enc 0x%02x\n", packet[11], packet[12]);
119                         debug_uart_tx(tstr);
120                         if (packet[2] == 0x00)
121                                 debug_uart_tx("connection established\n");
122                         else
123                                 debug_uart_tx("connection failed\n");
124 #endif
125                         break;
126                 case HCI_EVENT_CONNECTION_REQUEST: {
127                         uint8_t bd_addr[7];
128
129                         switch (packet[11]) {
130                                 case HCI_LINK_TYPE_SCO:
131                                         debug_uart_tx("SCO");
132                                         break;
133                                 case HCI_LINK_TYPE_ACL:
134                                         debug_uart_tx("ACL");
135                                         break;
136                                 case HCI_LINK_TYPE_ESCO:
137                                         debug_uart_tx("eSCO");
138                                         break;
139                                 default:
140                                         debug_uart_tx("unknown type");
141                                         break;
142                         }
143                         debug_uart_tx(" con req from ");
144                         for (i=0; i<6; i++) {
145                                 bd_addr[i] = packet[i+2];
146                         }
147                         bt_print_bd_addr(bd_addr);
148                         dev_type = (uint32_t)packet[8] << 16;
149                         dev_type |= (uint32_t)packet[9] << 8;
150                         dev_type |= packet[10];
151 #if defined MW_DEVBOARD_V2
152                         snprintf(tstr, 32, " rem. dtype 0x%06lx\n", dev_type);
153                         debug_uart_tx(tstr);
154 #endif
155                         //memcpy(tstr, bd_addr, 6);
156                         //tstr[6] = 0x01; /* remain slave */
157                         bd_addr[6] = 0x01; /* remain slave */
158                         bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_ACCEPT_CONN_REQ_OCF, 7, bd_addr);
159                         } break;
160                 case HCI_EVENT_DISCONNECTION_COMPLETE:
161                         debug_uart_tx("discon complete\n");
162                         break;
163                 case HCI_EVENT_AUTHENTICATION_COMPLETE_EVENT:
164                         debug_uart_tx("auth complete\n");
165                         break;
166                 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
167                         debug_uart_tx("rem name req complete\n");
168                         break;
169                 case HCI_EVENT_ENCRYPTION_CHANGE:
170                         debug_uart_tx("enc change\n");
171                         break;
172                 case HCI_EVENT_CHANGE_CONNECTION_LINK_KEY_COMPLETE:
173                         debug_uart_tx("change con link key complete\n");
174                         break;
175                 case HCI_EVENT_MASTER_LINK_KEY_COMPLETE:
176                         debug_uart_tx("master link key complete\n");
177                         break;
178                 case HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
179                         debug_uart_tx("read rem feat. complete\n");
180                         break;
181                 case HCI_EVENT_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
182                         debug_uart_tx("read rem version complete\n");
183                         break;
184                 case HCI_EVENT_QOS_SETUP_COMPLETE:
185                         debug_uart_tx("qos setup complete\n");
186                         break;
187                 case HCI_EVENT_COMMAND_COMPLETE:
188                         // snprintf(tstr, 32, "%d cmd(s) complete: 0x%02x%02x=%d", packet[2], packet[3], packet[4], packet[5]);
189                         // debug_uart_tx(tstr);
190                         if (packet[2] > 0 &&
191                             packet[3] == ((HCI_R_BD_ADDR_OCF | (HCI_INFO_PARAM_OGF << 10)) & 0xff) &&
192                             packet[4] == (((HCI_R_BD_ADDR_OCF | (HCI_INFO_PARAM_OGF << 10)) & 0xff00) >> 8)) { // read local bdaddr
193                                 memcpy(local_bdaddr, (packet+6), 6);
194 #if defined MW_DEVBOARD_V2
195                                 debug_uart_tx("local bdaddr = ");
196                                 bt_print_bd_addr((uint8_t *)(packet+6));
197                                 debug_uart_tx("\n");
198 #endif
199                         }
200                         break;
201                 case HCI_EVENT_COMMAND_STATUS:
202                         debug_uart_tx("cmd status\n");
203                         break;
204                 case HCI_EVENT_HARDWARE_ERROR:
205 #if defined MW_DEVBOARD_V2
206                         debug_uart_tx("hardw err");
207                         snprintf(tstr, 32, " 0x%02x\n", packet[2]);
208                         debug_uart_tx(tstr);
209 #endif
210                         break;
211                 case HCI_EVENT_FLUSH_OCCURED:
212                         debug_uart_tx("flush occured\n");
213                         break;
214                 case HCI_EVENT_ROLE_CHANGE:
215                         debug_uart_tx("role change\n");
216                         break;
217                 case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
218                         debug_uart_tx("numb compl. packets\n");
219                         break;
220                 case HCI_EVENT_MODE_CHANGE_EVENT:
221                         debug_uart_tx("mode change\n");
222                         break;
223                 case HCI_EVENT_RETURN_LINK_KEYS:
224                         debug_uart_tx("return link keys\n");
225                         break;
226                 case HCI_EVENT_PIN_CODE_REQUEST:
227                         debug_uart_tx("pin code request\n");
228 #if defined MW_DEVBOARD_V2
229                         debug_uart_tx("from ");
230                         bt_print_bd_addr((uint8_t *)(packet+2));
231                         debug_uart_tx("\n");
232 #endif
233                         memmove(packet, (packet+2), 6);
234                         packet[6] = 0x04; // PIN has length of 4
235                         memcpy((packet+7), BT_PIN, 4);
236                         packet[7] = '4';
237                         packet[8] = '3';
238                         packet[9] = '1';
239                         packet[10] = '2';
240                         bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_PIN_CODE_REQ_REP_OCF, 11, packet);
241                         break;
242                 case HCI_EVENT_LINK_KEY_REQUEST:
243                         debug_uart_tx("link key request\n");
244                         break;
245                 case HCI_EVENT_LINK_KEY_NOTIFICATION:
246                         debug_uart_tx("link key notify\n");
247                         break;
248                 case HCI_EVENT_DATA_BUFFER_OVERFLOW:
249                         debug_uart_tx("evt data buf overflow\n");
250                         break;
251                 case HCI_EVENT_MAX_SLOTS_CHANGED:
252                         debug_uart_tx("max slots changed\n");
253                         break;
254                 case HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE:
255                         debug_uart_tx("read clock offset compl.\n");
256                         break;
257                 case HCI_EVENT_PACKET_TYPE_CHANGED:
258                         debug_uart_tx("packet type changed\n");
259                         break;
260                 case HCI_EVENT_PAGE_SCAN_REPETION_MODE_CHANGE:
261                         debug_uart_tx("page scan repetition mode changed\n");
262                         break;
263                 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
264                         debug_uart_tx("inq result with RSSI\n");
265                         break;
266                 case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
267                         debug_uart_tx("ext. inq. resp.\n");
268                         break;
269                 case HCI_EVENT_LE_META:
270                         debug_uart_tx("LE meta\n");
271                         break;
272                 case HCI_EVENT_VENDOR_SPECIFIC:
273                         debug_uart_tx("vend. spec.\n");
274                         break;
275                 default:
276                         debug_uart_tx("unknown\n");
277                         break;
278         }
279 //      debug_uart_tx("\n");
280 //      for (i=2; i<=(packet[1]+1); i++) {
281 //              snprintf(tstr, 32, " 0x%02x", packet[i]);
282 //              debug_uart_tx(tstr);
283 //      }
284 //      debug_uart_tx("\n");
285 }
286
287 typedef enum {
288         HCI_PACKET_START = 0,
289         HCI_CMD_PACKET,
290         HCI_ACL_PACKET_HEADER,
291         HCI_ACL_PACKET_DATA,
292         HCI_SCO_PACKET,
293         HCI_EVENT_PACKET_HEADER,
294         HCI_EVENT_PACKET_DATA,
295         HCI_EHCILL_PACKET,
296         EHCILL_SLEEPING
297 } bt_hci_state_t;
298
299 static bt_hci_state_t state = HCI_PACKET_START;
300
301 unsigned char bt_feed_packet_data(unsigned char pdata)
302 {
303         char tstr[32];
304         static unsigned char packet[255];
305         static uint16_t bytes_left = 0;
306         static uint16_t pdata_pos = 0;
307
308 //      snprintf(tstr, 32, "bt 0x%02x ", pdata);
309 //      debug_uart_tx(tstr);
310         switch (state) {
311                 case HCI_PACKET_START:
312                         switch (pdata) {
313                                 case HCI_EVENT_PACKET:
314                                         state = HCI_EVENT_PACKET_HEADER;
315                                         bytes_left = 1;
316                                         pdata_pos = 0;
317                                         memset(packet, 0, 64);
318                                         break;
319                                 case HCI_ACL_DATA_PACKET:
320                                         state = HCI_ACL_PACKET_HEADER;
321                                         bytes_left = 3;
322                                         pdata_pos = 0;
323                                         memset(packet, 0, 64);
324                                         break;
325                                 case EHCILL_GO_TO_SLEEP_IND:
326                                         debug_uart_tx("eHCILL go to sleep ind\n");
327                                         state = HCI_PACKET_START;
328                                         // disable BT UART?
329                                         // mabye UCA1CTL1 = UCSWRST ?
330
331                                         pdata = EHCILL_GO_TO_SLEEP_ACK;
332                                         mw_bt_uart_tx(&pdata, 0x01);
333
334                                         // pull RTS -> stop data
335                                         BT_IO_POUT |= BT_IO_RTS;
336
337                                         // enable IRQ on CTS
338                                         P1IFG &= ~BT_IO_CTS;
339                                         P1IE |= BT_IO_CTS;
340
341                                         state = EHCILL_SLEEPING;
342                                         break;
343                                 case EHCILL_GO_TO_SLEEP_ACK:
344                                         debug_uart_tx("eHCILL go to sleep ack\n");
345                                         state = HCI_PACKET_START;
346                                         break;
347                                 case EHCILL_WAKE_UP_IND:
348                                         debug_uart_tx("eHCILL wake up ind\n");
349                                         state = HCI_PACKET_START;
350                                         break;
351                                 case EHCILL_WAKE_UP_ACK:
352                                         debug_uart_tx("eHCILL wake up ack\n");
353                                         state = HCI_PACKET_START;
354                                         break;
355                                 default:
356                                         debug_uart_tx("unexpected packet start\n");
357                                         break;
358                         }
359                         break;
360                 case HCI_EVENT_PACKET_HEADER:
361                         if (bytes_left != 0) {
362                                 packet[pdata_pos++] = pdata;
363                                 bytes_left--;
364                         } else {
365                                 state = HCI_EVENT_PACKET_DATA;
366                                 packet[pdata_pos++] = pdata;
367                                 bytes_left = pdata;
368                         }
369                         break;
370                 case HCI_EVENT_PACKET_DATA:
371                         packet[pdata_pos++] = pdata;
372                         bytes_left--;
373                         if (bytes_left == 0) {
374                                 state = HCI_PACKET_START;
375                                 bt_hci_process_event_packet(packet);
376                         }
377                         break;
378                 case HCI_ACL_PACKET_HEADER:
379                         if (bytes_left != 0) {
380                                 packet[pdata_pos++] = pdata;
381                                 bytes_left--;
382                         } else {
383                                 state = HCI_ACL_PACKET_DATA;
384                                 packet[pdata_pos] = pdata;
385                                 bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
386 //                              snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
387 //                              debug_uart_tx(tstr);
388 //                              snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
389 //                              debug_uart_tx(tstr);
390                                 pdata_pos++;
391                         }
392                         break;
393                 case HCI_ACL_PACKET_DATA:
394 //                      snprintf(tstr, 32, "%02x ", pdata);
395 //                      debug_uart_tx(tstr);
396                         packet[pdata_pos++] = pdata;
397                         bytes_left--;
398                         if (bytes_left == 0) {
399 //                              debug_uart_tx("\n");
400                                 state = HCI_PACKET_START;
401                                 bt_hci_process_acl_packet(packet);
402                         }
403                         break;
404                 default:
405                         debug_uart_tx("hosed HCI state!\n");
406                         snprintf(tstr, 32, "  state = %d\n", state);
407                         debug_uart_tx(tstr);
408                         break;
409         };
410
411         // one byte consumed
412         return 1;
413 }
414
415 typedef struct {
416         uint8_t type;
417         uint16_t cmd;
418         uint8_t length;
419 } __attribute__((packed)) bt_hci_cmd_t;
420
421 void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, const void *data)
422 {
423         bt_hci_cmd_t packet;
424
425         // refuse any HCI if interface is not enabled
426         if (mw_bt_is_enabled() == 0)
427                 return;
428
429         if (state == EHCILL_SLEEPING) {
430                 uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
431
432                 debug_uart_tx("wakeup HCILL\n");
433                 state = HCI_PACKET_START;
434                 mw_bt_uart_tx(&ehcill_p, 1);
435                 __delay_cycles(300000);
436                 BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
437         }
438         packet.type = HCI_COMMAND_PACKET;
439         packet.cmd = OCF | (OGF<<10);
440         packet.length = data_len;
441         mw_bt_uart_tx(&packet, sizeof(bt_hci_cmd_t));
442         if (data_len > 0 && data != NULL)
443                 mw_bt_uart_tx(data, data_len);
444 }
445
446 typedef struct {
447         uint16_t acl_handle;
448         uint16_t max_interval;
449         uint16_t min_interval;
450         uint16_t sniff_attempt;
451         uint16_t sniff_timeout;
452 } __attribute__((packed)) bt_hci_sniff_cmd_t;
453
454 void bt_hci_set_sniff_mode(const uint16_t acl_handle, const uint16_t max_interval, const uint16_t min_interval, const uint16_t sniff_attempt, const uint16_t sniff_timeout)
455 {
456         bt_hci_sniff_cmd_t sniff_cmd;
457
458         sniff_cmd.acl_handle = acl_handle;
459         sniff_cmd.max_interval = max_interval;
460         sniff_cmd.min_interval = min_interval;
461         sniff_cmd.sniff_attempt = sniff_attempt;
462         sniff_cmd.sniff_timeout = sniff_timeout;
463         
464         bt_hci_cmd(HCI_LINK_POLICY_OGF, HCI_SNIFF_MODE_OCF, sizeof(sniff_cmd), &sniff_cmd);
465 }
466
467 typedef struct {
468         uint8_t type;
469         uint16_t handle;
470         uint16_t total_length;
471         uint16_t data_length;
472         uint16_t channel;
473 } __attribute__((packed)) bt_hci_acl_t;
474
475 void bt_acl_send(const uint16_t handle, const uint8_t PB, const uint8_t BC, const uint16_t channel, const uint16_t dlen, const void *dat)
476 {
477         bt_hci_acl_t packet;
478
479         // refuse any HCI if interface is not enabled
480         if (mw_bt_is_enabled() == 0)
481                 return;
482
483         packet.type = HCI_ACL_DATA_PACKET;
484         packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
485         packet.total_length = dlen + 4;
486         packet.data_length = dlen;
487         packet.channel = channel;
488         mw_bt_uart_tx(&packet, sizeof(bt_hci_acl_t));
489         mw_bt_uart_tx(dat, dlen);
490 }
491
492 void bt_hci_init(void)
493 {
494         state = HCI_PACKET_START;
495 }
496
497 void bt_hci_ehcill_wake(void)
498 {
499         const uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
500
501         debug_uart_tx("HCILL wakeup\n");
502
503         P1IE &= ~BT_IO_CTS;
504         P1IFG &= ~BT_IO_CTS;
505         state = HCI_PACKET_START;
506
507         BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
508
509         mw_bt_uart_tx(&ehcill_p, 1);
510         //__delay_cycles(160000);
511 }
512