brcm_patchram_plus.c revision ac8c432d8eea5f875f672c2a7755c40a76a3c8cd
1ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly/** 2ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * brcm_patchram_plus.c 3ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 4ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * Copyright (C) 2009 Broadcom Corporation. 5ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 6ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * This software is licensed under the terms of the GNU General Public License, 7ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * version 2, as published by the Free Software Foundation (the "GPL"), and may 8ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * be copied, distributed, and modified under those terms. 9ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 10ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * This program is distributed in the hope that it will be useful, but WITHOUT 11ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * FITNESS FOR A PARTICULAR PURPOSE. See the GPL for more details. 13ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 14ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * A copy of the GPL is available at http://www.broadcom.com/licenses/GPLv2.php 15ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * or by writing to the Free Software Foundation, Inc., 16ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 17ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly */ 18ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 19ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 20ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly/***************************************************************************** 21ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 22ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** Name: brcm_patchram_plus.c 23ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 24ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** Description: This program downloads a patchram files in the HCD format 25ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** to Broadcom Bluetooth based silicon and combo chips and 26ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** and other utility functions. 27ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 28ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** It can be invoked from the command line in the form 29ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <-d> to print a debug log 30ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--patchram patchram_file> 31ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--baudrate baud_rate> 32ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--bd_addr bd_address> 33ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--enable_lpm> 34ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** <--enable_hci> 35ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** uart_device_name 36ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 37ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** For example: 38ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 39ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** brcm_patchram_plus -d --patchram \ 40ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0 41ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 42ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** It will return 0 for success and a number greater than 0 43ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** for any errors. 44ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 45ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** For Android, this program invoked using a 46ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** "system(2)" call from the beginning of the bt_enable 47ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** function inside the file 48ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** mydroid/system/bluetooth/bluedroid/bluetooth.c. 49ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 50ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly** 51ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly******************************************************************************/ 52ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 53ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly// TODO: Integrate BCM support into Bluez hciattach 54ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 55ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <stdio.h> 56ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <getopt.h> 57ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <errno.h> 58ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 59ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/types.h> 60ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/stat.h> 61ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <fcntl.h> 62ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 63ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <stdlib.h> 64ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 65ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifdef ANDROID 66ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <termios.h> 67ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#else 68ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <sys/termios.h> 69ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 70ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 71ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <string.h> 72ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#include <signal.h> 73ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 74ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef N_HCI 75ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define N_HCI 15 76ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 77ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 78ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTSETPROTO _IOW('U', 200, int) 79ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTGETPROTO _IOR('U', 201, int) 80ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCIUARTGETDEVICE _IOR('U', 202, int) 81ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 82ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_H4 0 83ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_BCSP 1 84ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_3WIRE 2 85ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_H4DS 3 86ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#define HCI_UART_LL 4 87ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 88ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 89ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint uart_fd = -1; 90ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint hcdfile_fd = -1; 91ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint termios_baudrate = 0; 92ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint bdaddr_flag = 0; 93ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint enable_lpm = 0; 94ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint enable_hci = 0; 95ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint debug = 0; 96ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 97ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellystruct termios termios; 98ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char buffer[1024]; 99ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 100ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 }; 101ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 102ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 }; 103ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 104ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00, 105ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00, 0x00, 0x00, 0x00 }; 106ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 107ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06, 108ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00 }; 110ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 111ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyunsigned char hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c, 112ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 113ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 0x00, 0x00 }; 114ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 115ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 116ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_patchram(char *optarg) 117ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 118ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly char *p; 119ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 120ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (!(p = strrchr(optarg, '.'))) { 121ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s not an HCD file\n", optarg); 122ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(3); 123ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 124ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 125ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly p++; 126ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 127ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (strcasecmp("hcd", p) != 0) { 128ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s not an HCD file\n", optarg); 129ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(4); 130ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 131ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 132ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) { 133ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno); 134ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(5); 135ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 136ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 137ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 138ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 139ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 140ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 141ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick PellyBRCM_encode_baud_rate(uint baud_rate, unsigned char *encoded_baud) 142ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 143ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if(baud_rate == 0 || encoded_baud == NULL) { 144ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Baudrate not supported!"); 145ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 146ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 147ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 148ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[3] = (unsigned char)(baud_rate >> 24); 149ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[2] = (unsigned char)(baud_rate >> 16); 150ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[1] = (unsigned char)(baud_rate >> 8); 151ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly encoded_baud[0] = (unsigned char)(baud_rate & 0xFF); 152ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 153ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 154ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellytypedef struct { 155ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int baud_rate; 156ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int termios_value; 157ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} tBaudRates; 158ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 159ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick PellytBaudRates baud_rates[] = { 160ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 115200, B115200 }, 161ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 230400, B230400 }, 162ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 460800, B460800 }, 163ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 500000, B500000 }, 164ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 576000, B576000 }, 165ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 921600, B921600 }, 166ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1000000, B1000000 }, 167ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1152000, B1152000 }, 168ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 1500000, B1500000 }, 169ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 2000000, B2000000 }, 170ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 2500000, B2500000 }, 171ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 3000000, B3000000 }, 172ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef __CYGWIN__ 173ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 3500000, B3500000 }, 174ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 4000000, B4000000 } 175ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 176ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly}; 177ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 178ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 179ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvalidate_baudrate(int baud_rate, int *value) 180ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 181ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly unsigned int i; 182ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 183ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) { 184ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (baud_rates[i].baud_rate == baud_rate) { 185ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly *value = baud_rates[i].termios_value; 186ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(1); 187ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 188ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 189ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 190ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 191ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 192ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 193ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 194ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_baudrate(char *optarg) 195ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 196ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int baudrate = atoi(optarg); 197ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 198ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (validate_baudrate(baudrate, &termios_baudrate)) { 199ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]); 200ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 201ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 202ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 203ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 204ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 205ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 206ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_bdaddr(char *optarg) 207ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 208ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int bd_addr[6]; 209ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i; 210ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 211ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly sscanf(optarg, "%02x%02x%02x%02x%02x%02x", 212ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly &bd_addr[0], &bd_addr[1], &bd_addr[2], 213ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly &bd_addr[3], &bd_addr[4], &bd_addr[5]); 214ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 215ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < 6; i++) { 216ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_write_bd_addr[4 + i] = bd_addr[i]; 217ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 218ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 219ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly bdaddr_flag = 1; 220ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 221ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 222ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 223ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 224ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 225ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_enable_lpm(char *optarg) 226ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 227ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly enable_lpm = 1; 228ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 229ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 230ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 231ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 232ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_enable_hci(char *optarg) 233ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 234ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly enable_hci = 1; 235ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 236ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 237ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 238ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 239ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyparse_cmd_line(int argc, char **argv) 240ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 241ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int c; 242ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int digit_optind = 0; 243ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 244ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly typedef int (*PFI)(); 245ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 246ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly PFI parse_param[] = { parse_patchram, parse_baudrate, 247ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly parse_bdaddr, parse_enable_lpm, parse_enable_hci }; 248ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 249ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while (1) 250ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly { 251ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int this_option_optind = optind ? optind : 1; 252ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int option_index = 0; 253ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 254ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly static struct option long_options[] = { 255ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {"patchram", 1, 0, 0}, 256ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {"baudrate", 1, 0, 0}, 257ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {"bd_addr", 1, 0, 0}, 258ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {"enable_lpm", 0, 0, 0}, 259ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {"enable_hci", 0, 0, 0}, 260ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly {0, 0, 0, 0} 261ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly }; 262ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 263ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly c = getopt_long_only (argc, argv, "d", long_options, &option_index); 264ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 265ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (c == -1) { 266ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly break; 267ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 268ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 269ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly switch (c) { 270ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly case 0: 271ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf ("option %s", long_options[option_index].name); 272ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 273ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (optarg) { 274ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf (" with arg %s", optarg); 275ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 276ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 277ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf ("\n"); 278ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 279ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly (*parse_param[option_index])(optarg); 280ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly break; 281ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 282ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly case 'd': 283ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly debug = 1; 284ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly break; 285ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 286ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly case '?': 287ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly //nobreak 288ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly default: 289ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 290ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("Usage %s:\n", argv[0]); 291ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<-d> to print a debug log\n"); 292ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<--patchram patchram_file>\n"); 293ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<--baudrate baud_rate>\n"); 294ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<--bd_addr bd_address>\n"); 295ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<--enable_lpm\n"); 296ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\t<--enable_hci\n"); 297ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf("\tuart_device_name\n"); 298ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly break; 299ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 300ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 301ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 302ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 303ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (optind < argc) { 304ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (optind < argc) { 305ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf ("%s ", argv[optind]); 306ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 307ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) { 308ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "port %s could not be opened, error %d\n", argv[2], errno); 309ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 310ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 311ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 312ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly printf ("\n"); 313ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 314ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 315ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return(0); 316ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 317ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 318ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 319ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyinit_uart() 320ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 321ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 322ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcgetattr(uart_fd, &termios); 323ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 324ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#ifndef __CYGWIN__ 325ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfmakeraw(&termios); 326ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#else 327ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 328ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly | INLCR | IGNCR | ICRNL | IXON); 329ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_oflag &= ~OPOST; 330ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 331ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag &= ~(CSIZE | PARENB); 332ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag |= CS8; 333ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly#endif 334ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 335ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly termios.c_cflag |= CRTSCTS; 336ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 337ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 338ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 339ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 340ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcflush(uart_fd, TCIOFLUSH); 341ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetospeed(&termios, B115200); 342ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetispeed(&termios, B115200); 343ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 344ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 345ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 346ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 347ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellydump(unsigned char *out, int len) 348ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 349ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i; 350ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 351ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly for (i = 0; i < len; i++) { 352ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (i && !(i % 16)) { 353ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "\n"); 354ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 355ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 356ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "%02x ", out[i]); 357ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 358ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 359ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "\n"); 360ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 361ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 362ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 363ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyread_event(int fd, unsigned char *buffer) 364ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 365ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i = 0; 366ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int len = 3; 367ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int count; 368ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 369ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while ((count = read(fd, &buffer[i], len)) < len) { 370ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 371ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len -= count; 372ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 373ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 374ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 375ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len = buffer[2]; 376ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 377ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while ((count = read(fd, &buffer[i], len)) < len) { 378ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly i += count; 379ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len -= count; 380ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 381ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 382ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 383ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly count += i; 384ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 385ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "received %d\n", count); 386ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly dump(buffer, count); 387ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 388ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 389ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 390ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 391ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyhci_send_cmd(unsigned char *buf, int len) 392ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 393ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 394ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "writing\n"); 395ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly dump(buf, len); 396ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 397ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 398ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly write(uart_fd, buf, len); 399ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 400ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 401ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 402ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyexpired(int sig) 403ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 404ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_reset, sizeof(hci_reset)); 405ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(4); 406ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 407ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 408ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 409ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_reset() 410ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 411ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly signal(SIGALRM, expired); 412ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 413ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 414ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_reset, sizeof(hci_reset)); 415ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 416ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(4); 417ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 418ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 419ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 420ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly alarm(0); 421ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 422ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 423ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 424ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_patchram() 425ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 426ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int len; 427ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 428ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver)); 429ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 430ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 431ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 432ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read(uart_fd, &buffer[0], 2); 433ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 434ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while (read(hcdfile_fd, &buffer[1], 3)) { 435ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly buffer[0] = 0x01; 436ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 437ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly len = buffer[3]; 438ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 439ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read(hcdfile_fd, &buffer[4], len); 440ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 441ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(buffer, len + 4); 442ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 443ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 444ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 445ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 446ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_reset(); 447ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 448ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 449ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 450ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_baudrate() 451ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 452ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate)); 453ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 454ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 455ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 456ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetospeed(&termios, termios_baudrate); 457ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly cfsetispeed(&termios, termios_baudrate); 458ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly tcsetattr(uart_fd, TCSANOW, &termios); 459ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 460ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (debug) { 461ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Done setting baudrate\n"); 462ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 463ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 464ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 465ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 466ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_bdaddr() 467ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 468ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr)); 469ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 470ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 471ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 472ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 473ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 474ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_lpm() 475ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 476ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode)); 477ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 478ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly read_event(uart_fd, buffer); 479ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 480ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 481ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyvoid 482ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyproc_enable_hci() 483ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 484ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int i = N_HCI; 485ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly int proto = HCI_UART_H4; 486ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_lpm) { 487ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proto = HCI_UART_LL; 488ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 489ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (ioctl(uart_fd, TIOCSETD, &i) < 0) { 490ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Can't set line discipline\n"); 491ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 492ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 493ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 494ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) { 495ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Can't set hci protocol\n"); 496ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 497ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 498ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly fprintf(stderr, "Done setting line discpline\n"); 499ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly return; 500ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 501ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 502ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellyint 503ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pellymain (int argc, char **argv) 504ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly{ 505ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly parse_cmd_line(argc, argv); 506ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 507ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (uart_fd < 0) { 508ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(1); 509ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 510ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 511ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly init_uart(); 512ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 513ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_reset(); 514ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 515ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (hcdfile_fd > 0) { 516ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_patchram(); 517ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 518ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 519ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (termios_baudrate) { 520ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_baudrate(); 521ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 522ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 523ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (bdaddr_flag) { 524ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_bdaddr(); 525ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 526ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 527ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_hci) { 528ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_enable_hci(); 529ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 530ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 531ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_lpm) { 532ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly proc_enable_lpm(); 533ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 534ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 535ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly if (enable_hci) { 536ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly while (1) { 537ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly sleep(UINT_MAX); 538ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 539ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly } 540ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly 541ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly exit(0); 542ac8c432d8eea5f875f672c2a7755c40a76a3c8cdNick Pelly} 543