00001 /* 00002 * Copyright (C) 2000-2005 by ETH Zurich 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY ETH ZURICH AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00019 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00020 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ETH ZURICH 00021 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00023 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00027 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * For additional information see http://www.ethernut.de/ 00031 * 00032 * $Id: btreceiver.c,v 1.16 2007/02/15 16:30:49 freckle Exp $ 00033 */ 00078 #ifdef __BTN_UNIX__ 00079 #include <dev/unix_devs.h> 00080 #include <unistd.h> 00081 #endif 00082 00083 #include <stdio.h> 00084 #include <string.h> 00085 #include <io.h> 00086 #include <stdlib.h> 00087 #include <dev/debug.h> 00088 #include <sys/timer.h> 00089 #include <sys/event.h> 00090 #include <dev/uartavr.h> 00091 #include <dev/usartavr.h> 00092 #include <bt/bt_hci_cmds.h> 00093 #include <hardware/btn-hardware.h> 00094 #include <led/btn-led.h> 00095 00096 00101 #define HCI_MAX_ACL_DATA_PKT 0x08 00102 00103 #define HCI_MAX_SCO_DATA_PKT 0x01 00104 00105 #define HCI_PACKET_TYPE BT_HCI_PACKET_TYPE_DH3 00106 00107 //Global variables on the heap 00108 struct btstack *stack; 00109 struct bt_hci_inquiry_result inqres[5]; 00110 struct bt_hci_pkt_acl *aclpkt; 00111 00112 bt_hci_con_handle_t THE_handle; 00113 HANDLE table_changed_event; 00114 HANDLE ten_event; 00115 00116 u_short packet_counter; 00117 00118 void change_con_pkt_type(bt_hci_con_handle_t con_handle) { 00119 long res; 00120 printf("change con pkt type to 0x%.4x\n",HCI_PACKET_TYPE); 00121 res = bt_hci_change_con_pkt_type(stack, BT_HCI_SYNC, con_handle, HCI_PACKET_TYPE); 00122 if (res < 0) 00123 printf("pkt change: error\n"); 00124 else { 00125 printf("pkt changed to 0x%.4lx\n",res); 00126 } 00127 } 00128 00129 00130 void con_table_cb(u_char type, u_char reason, bt_hci_con_handle_t con_handle, void* cb_arg) 00131 { 00132 printf("\nconnection table changed!\n"); 00133 switch (type) { 00134 case BT_HCI_MY_ROLE_MASTER: 00135 printf("CB: My role switched to master (%d)\n",con_handle); 00136 break; 00137 case BT_HCI_MY_ROLE_SLAVE: 00138 printf("CB: My role switched to slave (%d)\n",con_handle); 00139 break; 00140 case BT_HCI_CONNECTION: 00141 printf("CB: Connection opened (%d)\n",con_handle); 00142 THE_handle = con_handle; 00143 NutEventPostAsync(&table_changed_event); 00144 break; 00145 case BT_HCI_DISCONNECTION: 00146 printf("CB: Disconnected (%d)\n",con_handle); 00147 break; 00148 default: 00149 printf("Illegal type entered! (%d)\n",type); 00150 } 00151 } 00152 00153 00154 struct bt_hci_pkt_acl *stream_receive(void *arg, struct bt_hci_pkt_acl *pkt, bt_hci_con_handle_t app_con_handle, 00155 u_char pb_flag, u_char bc_flag, u_short len, u_long t_arrive) 00156 { 00157 long retval; 00158 u_short acllen, i; 00159 // printf("Acl pkt. from handle %d with pb=%d, bc=%c of len %d dropped\n\r", app_con_handle, pb_flag, bc_flag, len); 00160 00161 acllen = pkt->payload[0] | pkt->payload[1]<<8; 00162 if (acllen != 183) { printf("Wrong ACL packet length: %d\n", acllen); } 00163 00164 for (i=10; i<183; i++) { 00165 if (pkt->payload[i] != i-2) { printf("Wrong data at position %d: %d\n", i, pkt->payload[i]); } 00166 } 00167 00168 /* DEBUG("Data: %d\n", acllen); 00169 for (i=0; i<acllen-2; i++) { 00170 DEBUG("%c", pkt->payload[i+2]); 00171 } 00172 DEBUG("\n"); */ 00173 00174 if (++packet_counter==10) { 00175 printf("."); 00176 packet_counter = 0; 00177 // NutEventPostAsync(&ten_event); 00178 } 00179 00180 // Free this pkt! 00181 retval = bt_hci_acl_free_buffer((struct btstack*)arg, app_con_handle, 1); 00182 // printf("pkt freed: %ld \n\r", retval); 00183 return pkt; 00184 } 00185 00186 int main(void) 00187 { 00188 long retval; 00189 u_long baud = 57600; 00190 char name[64]; 00191 u_long myTime; 00192 u_long masterTime; 00193 00194 // hardware init 00195 btn_hardware_init(); 00196 btn_led_init(1); 00197 00198 // init app uart 00199 NutRegisterDevice(&APP_UART, 0, 0); 00200 freopen(APP_UART.dev_name, "r+", stdout); 00201 _ioctl(_fileno(stdout), UART_SETSPEED, &baud); 00202 00203 // bluetooth module on (takes a while) 00204 btn_hardware_bt_on(); 00205 00206 // Start the stack and let the initializaiton begin 00207 stack = bt_hci_init(&BT_UART); 00208 00209 // Set the speed to 57600 00210 // retval = bt_hci_set_baudrate(stack, BT_HCI_B57600); 00211 // if (retval != 0) printf("Setting the baudrate to 115200: %ld\n", retval); 00212 // Set the speed to 115200 00213 // retval = bt_hci_set_baudrate(stack, BT_HCI_B115200); 00214 // if (retval != 0) printf("Setting the baudrate to 115200: %ld\n", retval); 00215 // Set the speed to 230400 00216 // retval = bt_hci_set_baudrate(stack, BT_HCI_B230400); 00217 // if (retval != 0) printf("Setting the baudrate to BT_HCI_B230400: %ld\n", retval); 00218 00219 // add connection handling to allow role change 00220 bt_hci_register_con_table_cb(stack, &con_table_cb, NULL); 00221 00222 // prepare data reception 00223 aclpkt =(struct bt_hci_pkt_acl *) malloc( 200 ); 00224 bt_hci_register_cl_acl_cb(stack, &stream_receive, aclpkt, stack); 00225 00226 // From now on the stack should be working... 00227 00228 strcpy(name, "BT-Receiver"); 00229 retval = bt_hci_write_local_name(stack, BT_HCI_SYNC, (u_char*) name); 00230 if (retval!=0) printf("Setting the btname: %ld\n", retval); 00231 00232 // Dirty hack: 00233 // We have only one packet, and the max.size is BT_HCI_MAX_DATA_PACKET 00234 // but we know that it will never be fragmented! 00235 retval = bt_hci_host_buffer_size(stack, BT_HCI_SYNC, 600, 0, 8, 0); 00236 printf("Set host buffer size: %ld\n", retval); 00237 00238 // Loop forever 00239 printf("Entering main loop, ready to receive data!\n"); 00240 00241 // Loop forever 00242 table_changed_event = 0; 00243 packet_counter = 0; 00244 while (1) { 00245 printf("LOOP (MAIN)\n"); 00246 // change connection pkt type and link policy for incoming connections 00247 // does not handle multiple incoming connections in short time 00248 NutEventWait(&table_changed_event,NUT_WAIT_INFINITE); 00249 //change_con_pkt_type(THE_handle); 00250 retval = bt_hci_write_link_policy_settings(stack, BT_HCI_SYNC, THE_handle, BT_HCI_LINK_POLICY_ROLE_SWITCH); 00251 00252 while ( 1 ) { 00253 NutEventWait( &ten_event,NUT_WAIT_INFINITE ); 00254 myTime = bt_hci_read_clock( stack, BT_HCI_SYNC, 0, 0, NULL, NULL); 00255 retval = bt_hci_read_clock_offset( stack, BT_HCI_SYNC, THE_handle); 00256 if (retval < 16484 ) 00257 masterTime = myTime - retval; 00258 else 00259 masterTime = myTime - retval + 32768; 00260 printf("%.6lu %.6lu %.6lu \r", masterTime, myTime, retval); 00261 } 00262 } 00263 return 0; 00264 }