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.13 2006/10/27 14:53:52 yuecelm Exp $ 00033 * 00034 */ 00035 00068 #ifdef __BTN_UNIX__ 00069 #include <dev/unix_devs.h> 00070 #include <unistd.h> 00071 #endif 00072 00073 #include <stdio.h> 00074 #include <string.h> 00075 #include <io.h> 00076 #include <stdlib.h> 00077 #include <dev/debug.h> 00078 #include <sys/timer.h> 00079 #include <sys/event.h> 00080 #include <dev/uartavr.h> 00081 #include <dev/usartavr.h> 00082 #include <bt/bt_hci_cmds.h> 00083 #include <hardware/btn-hardware.h> 00084 #include <led/btn-led.h> 00085 00086 00091 #define HCI_MAX_ACL_DATA_PKT 0x08 00092 00093 #define HCI_MAX_SCO_DATA_PKT 0x01 00094 00095 #define HCI_PACKET_TYPE BT_HCI_PACKET_TYPE_DH3 00096 00097 //Global variables on the heap 00098 struct btstack *stack; 00099 struct bt_hci_inquiry_result inqres[5]; 00100 struct bt_hci_pkt_acl *aclpkt; 00101 00102 bt_hci_con_handle_t THE_handle; 00103 HANDLE table_changed_event; 00104 00105 u_short packet_counter; 00106 00107 void change_con_pkt_type(bt_hci_con_handle_t con_handle) { 00108 long res; 00109 printf("change con pkt type to 0x%.4x\n",HCI_PACKET_TYPE); 00110 res = bt_hci_change_con_pkt_type(stack, BT_HCI_SYNC, con_handle, HCI_PACKET_TYPE); 00111 if (res < 0) 00112 printf("pkt change: error\n"); 00113 else { 00114 printf("pkt changed to 0x%.4lx\n",res); 00115 } 00116 } 00117 00118 00119 void con_table_cb(u_char type, u_char reason, bt_hci_con_handle_t con_handle, void* cb_arg) 00120 { 00121 printf("\nconnection table changed!\n"); 00122 switch (type) { 00123 case BT_HCI_MY_ROLE_MASTER: 00124 printf("CB: My role switched to master (%d)\n",con_handle); 00125 break; 00126 case BT_HCI_MY_ROLE_SLAVE: 00127 printf("CB: My role switched to slave (%d)\n",con_handle); 00128 break; 00129 case BT_HCI_CONNECTION: 00130 printf("CB: Connection opened (%d)\n",con_handle); 00131 THE_handle = con_handle; 00132 NutEventPostAsync(&table_changed_event); 00133 break; 00134 case BT_HCI_DISCONNECTION: 00135 printf("CB: Disconnected (%d)\n",con_handle); 00136 break; 00137 default: 00138 printf("Illegal type entered! (%d)\n",type); 00139 } 00140 } 00141 00142 00143 struct bt_hci_pkt_acl *stream_receive(void *arg, struct bt_hci_pkt_acl *pkt, bt_hci_con_handle_t app_con_handle, 00144 u_char pb_flag, u_char bc_flag, u_short len, u_long t_arrive) 00145 { 00146 long retval; 00147 u_short acllen, i; 00148 // 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); 00149 00150 acllen = pkt->payload[0] | pkt->payload[1]<<8; 00151 if (acllen != 183) { printf("Wrong ACL packet length: %d\n", acllen); } 00152 00153 for (i=2; i<183; i++) { 00154 if (pkt->payload[i] != i-2) { printf("Wrong data at position %d: %d\n", i, pkt->payload[i]); } 00155 } 00156 00157 /* DEBUG("Data: %d\n", acllen); 00158 for (i=0; i<acllen-2; i++) { 00159 DEBUG("%c", pkt->payload[i+2]); 00160 } 00161 DEBUG("\n"); */ 00162 00163 if (++packet_counter==10) { 00164 printf("."); 00165 packet_counter = 0; 00166 } 00167 00168 // Free this pkt! 00169 retval = bt_hci_acl_free_buffer((struct btstack*)arg, app_con_handle, 1); 00170 // printf("pkt freed: %ld \n\r", retval); 00171 return pkt; 00172 } 00173 00174 int main(void) 00175 { 00176 long retval; 00177 u_long baud = 57600; 00178 char name[64]; 00179 00180 // hardware init 00181 btn_hardware_init(); 00182 btn_led_init(1); 00183 00184 // init app uart 00185 NutRegisterDevice(&APP_UART, 0, 0); 00186 freopen(APP_UART.dev_name, "r+", stdout); 00187 _ioctl(_fileno(stdout), UART_SETSPEED, &baud); 00188 00189 // bluetooth module on (takes a while) 00190 btn_hardware_bt_on(); 00191 00192 // Start the stack and let the initializaiton begin 00193 stack = bt_hci_init(&BT_UART); 00194 00195 // Set the speed to 57600 00196 // retval = bt_hci_set_baudrate(stack, BT_HCI_B57600); 00197 // if (retval != 0) printf("Setting the baudrate to 115200: %ld\n", retval); 00198 // Set the speed to 115200 00199 // retval = bt_hci_set_baudrate(stack, BT_HCI_B115200); 00200 // if (retval != 0) printf("Setting the baudrate to 115200: %ld\n", retval); 00201 // Set the speed to 230400 00202 // retval = bt_hci_set_baudrate(stack, BT_HCI_B230400); 00203 // if (retval != 0) printf("Setting the baudrate to BT_HCI_B230400: %ld\n", retval); 00204 00205 // add connection handling to allow role change 00206 bt_hci_register_con_table_cb(stack, &con_table_cb, NULL); 00207 00208 // prepare data reception 00209 aclpkt =(struct bt_hci_pkt_acl *) malloc( 200 ); 00210 bt_hci_register_acl_cb(stack, &stream_receive, aclpkt, stack); 00211 00212 // From now on the stack should be working... 00213 00214 strcpy(name, "BT-Receiver"); 00215 retval = bt_hci_write_local_name(stack, BT_HCI_SYNC, (u_char*) name); 00216 if (retval!=0) printf("Setting the btname: %ld\n", retval); 00217 00218 // Dirty hack: 00219 // We have only one packet, and the max.size is BT_HCI_MAX_DATA_PACKET 00220 // but we know that it will never be fragmented! 00221 retval = bt_hci_host_buffer_size(stack, BT_HCI_SYNC, 600, 0, 8, 0); 00222 printf("Set host buffer size: %ld\n", retval); 00223 00224 // Loop forever 00225 printf("Entering main loop, ready to receive data!\n"); 00226 00227 // Loop forever 00228 table_changed_event = 0; 00229 packet_counter = 0; 00230 while (1) { 00231 printf("LOOP (MAIN)\n"); 00232 // change connection pkt type and link policy for incoming connections 00233 // does not handle multiple incoming connections in short time 00234 NutEventWait(&table_changed_event,NUT_WAIT_INFINITE); 00235 //change_con_pkt_type(THE_handle); 00236 retval = bt_hci_write_link_policy_settings(stack, BT_HCI_SYNC, THE_handle, BT_HCI_LINK_POLICY_ROLE_SWITCH); 00237 } 00238 return 0; 00239 }