]> git.karo-electronics.de Git - oswald.git/blob - metawatch/bt_hci.c
Here we are! MetaWatch support in Oswald!
[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                         packet[7] = '4';
236                         packet[8] = '3';
237                         packet[9] = '1';
238                         packet[10] = '2';
239                         bt_hci_cmd(HCI_LINK_CTRL_OGF, HCI_PIN_CODE_REQ_REP_OCF, 11, packet);
240                         break;
241                 case HCI_EVENT_LINK_KEY_REQUEST:
242                         debug_uart_tx("link key request\n");
243                         break;
244                 case HCI_EVENT_LINK_KEY_NOTIFICATION:
245                         debug_uart_tx("link key notify\n");
246                         break;
247                 case HCI_EVENT_DATA_BUFFER_OVERFLOW:
248                         debug_uart_tx("evt data buf overflow\n");
249                         break;
250                 case HCI_EVENT_MAX_SLOTS_CHANGED:
251                         debug_uart_tx("max slots changed\n");
252                         break;
253                 case HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE:
254                         debug_uart_tx("read clock offset compl.\n");
255                         break;
256                 case HCI_EVENT_PACKET_TYPE_CHANGED:
257                         debug_uart_tx("packet type changed\n");
258                         break;
259                 case HCI_EVENT_PAGE_SCAN_REPETION_MODE_CHANGE:
260                         debug_uart_tx("page scan repetition mode changed\n");
261                         break;
262                 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
263                         debug_uart_tx("inq result with RSSI\n");
264                         break;
265                 case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
266                         debug_uart_tx("ext. inq. resp.\n");
267                         break;
268                 case HCI_EVENT_LE_META:
269                         debug_uart_tx("LE meta\n");
270                         break;
271                 case HCI_EVENT_VENDOR_SPECIFIC:
272                         debug_uart_tx("vend. spec.\n");
273                         break;
274                 default:
275                         debug_uart_tx("unknown\n");
276                         break;
277         }
278 //      debug_uart_tx("\n");
279 //      for (i=2; i<=(packet[1]+1); i++) {
280 //              snprintf(tstr, 32, " 0x%02x", packet[i]);
281 //              debug_uart_tx(tstr);
282 //      }
283 //      debug_uart_tx("\n");
284 }
285
286 typedef enum {
287         HCI_PACKET_START = 0,
288         HCI_CMD_PACKET,
289         HCI_ACL_PACKET_HEADER,
290         HCI_ACL_PACKET_DATA,
291         HCI_SCO_PACKET,
292         HCI_EVENT_PACKET_HEADER,
293         HCI_EVENT_PACKET_DATA,
294         HCI_EHCILL_PACKET,
295         EHCILL_SLEEPING
296 } bt_hci_state_t;
297
298 static bt_hci_state_t state = HCI_PACKET_START;
299
300 unsigned char bt_feed_packet_data(unsigned char pdata)
301 {
302         char tstr[32];
303         static unsigned char packet[255];
304         static uint16_t bytes_left = 0;
305         static uint16_t pdata_pos = 0;
306
307 //      snprintf(tstr, 32, "bt 0x%02x ", pdata);
308 //      debug_uart_tx(tstr);
309         switch (state) {
310                 case HCI_PACKET_START:
311                         switch (pdata) {
312                                 case HCI_EVENT_PACKET:
313                                         state = HCI_EVENT_PACKET_HEADER;
314                                         bytes_left = 1;
315                                         pdata_pos = 0;
316                                         memset(packet, 0, 64);
317                                         break;
318                                 case HCI_ACL_DATA_PACKET:
319                                         state = HCI_ACL_PACKET_HEADER;
320                                         bytes_left = 3;
321                                         pdata_pos = 0;
322                                         memset(packet, 0, 64);
323                                         break;
324                                 case EHCILL_GO_TO_SLEEP_IND:
325                                         debug_uart_tx("eHCILL go to sleep ind\n");
326                                         state = HCI_PACKET_START;
327                                         // disable BT UART?
328                                         // mabye UCA1CTL1 = UCSWRST ?
329                                         pdata = EHCILL_GO_TO_SLEEP_ACK;
330                                         mw_bt_uart_tx(&pdata, 0x01);
331                                         BT_IO_POUT |= BT_IO_RTS; // pull RTS -> stop data
332
333                                         P1IFG &= ~BT_IO_CTS;
334                                         P1IE |= BT_IO_CTS;
335
336                                         state = EHCILL_SLEEPING;
337                                         break;
338                                 case EHCILL_GO_TO_SLEEP_ACK:
339                                         debug_uart_tx("eHCILL go to sleep ack\n");
340                                         state = HCI_PACKET_START;
341                                         break;
342                                 case EHCILL_WAKE_UP_IND:
343                                         debug_uart_tx("eHCILL wake up ind\n");
344                                         state = HCI_PACKET_START;
345                                         break;
346                                 case EHCILL_WAKE_UP_ACK:
347                                         debug_uart_tx("eHCILL wake up ack\n");
348                                         state = HCI_PACKET_START;
349                                         break;
350                                 default:
351                                         debug_uart_tx("unexpected packet start\n");
352                                         break;
353                         }
354                         break;
355                 case HCI_EVENT_PACKET_HEADER:
356                         if (bytes_left != 0) {
357                                 packet[pdata_pos++] = pdata;
358                                 bytes_left--;
359                         } else {
360                                 state = HCI_EVENT_PACKET_DATA;
361                                 packet[pdata_pos++] = pdata;
362                                 bytes_left = pdata;
363                         }
364                         break;
365                 case HCI_EVENT_PACKET_DATA:
366                         packet[pdata_pos++] = pdata;
367                         bytes_left--;
368                         if (bytes_left == 0) {
369                                 state = HCI_PACKET_START;
370                                 bt_hci_process_event_packet(packet);
371                         }
372                         break;
373                 case HCI_ACL_PACKET_HEADER:
374                         if (bytes_left != 0) {
375                                 packet[pdata_pos++] = pdata;
376                                 bytes_left--;
377                         } else {
378                                 state = HCI_ACL_PACKET_DATA;
379                                 packet[pdata_pos] = pdata;
380                                 bytes_left = (packet[pdata_pos-1] | (packet[pdata_pos] << 8));
381 //                              snprintf(tstr, 32, "ACL data len 0x%04x\n", bytes_left);
382 //                              debug_uart_tx(tstr);
383 //                              snprintf(tstr, 32, "%d (0x%02x 0x%02x)\n", pdata_pos, packet[pdata_pos-1], packet[pdata_pos]);
384 //                              debug_uart_tx(tstr);
385                                 pdata_pos++;
386                         }
387                         break;
388                 case HCI_ACL_PACKET_DATA:
389 //                      snprintf(tstr, 32, "%02x ", pdata);
390 //                      debug_uart_tx(tstr);
391                         packet[pdata_pos++] = pdata;
392                         bytes_left--;
393                         if (bytes_left == 0) {
394 //                              debug_uart_tx("\n");
395                                 state = HCI_PACKET_START;
396                                 bt_hci_process_acl_packet(packet);
397                         }
398                         break;
399                 default:
400                         debug_uart_tx("hosed HCI state!\n");
401                         snprintf(tstr, 32, "  state = %d\n", state);
402                         debug_uart_tx(tstr);
403                         break;
404         };
405
406         // one byte consumed
407         return 1;
408 }
409
410 typedef struct {
411         uint8_t type;
412         uint16_t cmd;
413         uint8_t length;
414 } __attribute__((packed)) bt_hci_cmd_t;
415
416 void bt_hci_cmd(const uint8_t OGF, const uint8_t OCF, const uint8_t data_len, const void *data)
417 {
418         bt_hci_cmd_t packet;
419
420         if (state == EHCILL_SLEEPING) {
421                 uint8_t ehcill_p = EHCILL_WAKE_UP_IND;
422
423                 debug_uart_tx("HCILL wakeup\n");
424                 state = HCI_PACKET_START;
425                 mw_bt_uart_tx(&ehcill_p, 1);
426                 __delay_cycles(300000);
427                 BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
428         }
429         packet.type = HCI_COMMAND_PACKET;
430         packet.cmd = OCF | (OGF<<10);
431         packet.length = data_len;
432         mw_bt_uart_tx(&packet, sizeof(bt_hci_cmd_t));
433         if (data_len > 0 && data != NULL)
434                 mw_bt_uart_tx(data, data_len);
435 }
436
437 typedef struct {
438         uint8_t type;
439         uint16_t handle;
440         uint16_t total_length;
441         uint16_t data_length;
442         uint16_t channel;
443 } __attribute__((packed)) bt_hci_acl_t;
444
445 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)
446 {
447         bt_hci_acl_t packet;
448
449         packet.type = HCI_ACL_DATA_PACKET;
450         packet.handle = handle | ((PB & 0x03) << 12) | ((BC & 0x03) << 14);
451         packet.total_length = dlen + 4;
452         packet.data_length = dlen;
453         packet.channel = channel;
454         mw_bt_uart_tx(&packet, sizeof(bt_hci_acl_t));
455         mw_bt_uart_tx(dat, dlen);
456 }
457
458 void bt_hci_init(void)
459 {
460         state = HCI_PACKET_START;
461 }
462
463 void bt_hci_ehcill_wake(void)
464 {
465         uint8_t ehcill_p = EHCILL_WAKE_UP_ACK;
466
467         debug_uart_tx("HCILL wakeup\n");
468
469         P1IE &= ~BT_IO_CTS;
470         state = HCI_PACKET_START;
471
472         BT_IO_POUT &= ~BT_IO_RTS; // drop RTS -> start data
473
474         mw_bt_uart_tx(&ehcill_p, 1);
475         //__delay_cycles(160000);
476 }
477