]> git.karo-electronics.de Git - oswald.git/blob - metawatch/bt_hci.c
Starting to get rid of borrowed code (LcdDisplay, Fonts), integrate
[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                                         pdata = EHCILL_GO_TO_SLEEP_ACK;
331                                         mw_bt_uart_tx(&pdata, 0x01);
332                                         BT_IO_POUT |= BT_IO_RTS; // pull RTS -> stop data
333
334                                         P1IFG &= ~BT_IO_CTS;
335                                         P1IE |= BT_IO_CTS;
336
337                                         state = EHCILL_SLEEPING;
338                                         break;
339                                 case EHCILL_GO_TO_SLEEP_ACK:
340                                         debug_uart_tx("eHCILL go to sleep ack\n");
341                                         state = HCI_PACKET_START;
342                                         break;
343                                 case EHCILL_WAKE_UP_IND:
344                                         debug_uart_tx("eHCILL wake up ind\n");
345                                         state = HCI_PACKET_START;
346                                         break;
347                                 case EHCILL_WAKE_UP_ACK:
348                                         debug_uart_tx("eHCILL wake up ack\n");
349                                         state = HCI_PACKET_START;
350                                         break;
351                                 default:
352                                         debug_uart_tx("unexpected packet start\n");
353                                         break;
354                         }
355                         break;
356                 case HCI_EVENT_PACKET_HEADER:
357                         if (bytes_left != 0) {
358                                 packet[pdata_pos++] = pdata;
359                                 bytes_left--;
360                         } else {
361                                 state = HCI_EVENT_PACKET_DATA;
362                                 packet[pdata_pos++] = pdata;
363                                 bytes_left = pdata;
364                         }
365                         break;
366                 case HCI_EVENT_PACKET_DATA:
367                         packet[pdata_pos++] = pdata;
368                         bytes_left--;
369                         if (bytes_left == 0) {
370                                 state = HCI_PACKET_START;
371                                 bt_hci_process_event_packet(packet);
372                         }
373                         break;
374                 case HCI_ACL_PACKET_HEADER:
375                         if (bytes_left != 0) {
376                                 packet[pdata_pos++] = pdata;
377                                 bytes_left--;
378                         } else {
379                                 state = HCI_ACL_PACKET_DATA;
380                                 packet[pdata_pos] = pdata;
381                                 bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
382 //                              snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
383 //                              debug_uart_tx(tstr);
384 //                              snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
385 //                              debug_uart_tx(tstr);
386                                 pdata_pos++;
387                         }
388                         break;
389                 case HCI_ACL_PACKET_DATA:
390 //                      snprintf(tstr, 32, "%02x ", pdata);
391 //                      debug_uart_tx(tstr);
392                         packet[pdata_pos++] = pdata;
393                         bytes_left--;
394                         if (bytes_left == 0) {
395 //                              debug_uart_tx("\n");
396                                 state = HCI_PACKET_START;
397                                 bt_hci_process_acl_packet(packet);
398                         }
399                         break;
400                 default:
401                         debug_uart_tx("hosed HCI state!\n");
402                         snprintf(tstr, 32, "  state = %d\n", state);
403                         debug_uart_tx(tstr);
404                         break;
405         };
406
407         // one byte consumed
408         return 1;
409 }
410
411 typedef struct {
412         uint8_t type;
413         uint16_t cmd;
414         uint8_t length;
415 } __attribute__((packed)) bt_hci_cmd_t;
416
417 void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, const void *data)
418 {
419         bt_hci_cmd_t packet;
420
421         if (state == EHCILL_SLEEPING) {
422                 uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
423
424                 debug_uart_tx("HCILL wakeup\n");
425                 state = HCI_PACKET_START;
426                 mw_bt_uart_tx(&ehcill_p, 1);
427                 __delay_cycles(300000);
428                 BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
429         }
430         packet.type = HCI_COMMAND_PACKET;
431         packet.cmd = OCF | (OGF<<10);
432         packet.length = data_len;
433         mw_bt_uart_tx(&packet, sizeof(bt_hci_cmd_t));
434         if (data_len > 0 && data != NULL)
435                 mw_bt_uart_tx(data, data_len);
436 }
437
438 typedef struct {
439         uint8_t type;
440         uint16_t handle;
441         uint16_t total_length;
442         uint16_t data_length;
443         uint16_t channel;
444 } __attribute__((packed)) bt_hci_acl_t;
445
446 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)
447 {
448         bt_hci_acl_t packet;
449
450         packet.type = HCI_ACL_DATA_PACKET;
451         packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
452         packet.total_length = dlen + 4;
453         packet.data_length = dlen;
454         packet.channel = channel;
455         mw_bt_uart_tx(&packet, sizeof(bt_hci_acl_t));
456         mw_bt_uart_tx(dat, dlen);
457 }
458
459 void bt_hci_init(void)
460 {
461         state = HCI_PACKET_START;
462 }
463
464 void bt_hci_ehcill_wake(void)
465 {
466         uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
467
468         debug_uart_tx("HCILL wakeup\n");
469
470         P1IE &= ~BT_IO_CTS;
471         state = HCI_PACKET_START;
472
473         BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
474
475         mw_bt_uart_tx(&ehcill_p, 1);
476         //__delay_cycles(160000);
477 }
478