📄 bt_vendor.c
字号:
/* * bt_vendor.c -- Contains all vendor specific initialization and * custom commands to bluetooth HW. * * Copyright (C) 2000, 2001 Axis Communications AB * * Author: Mattias Agren <mattias.agren@axis.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Exceptionally, Axis Communications AB grants discretionary and * conditional permissions for additional use of the text contained * in the company's release of the AXIS OpenBT Stack under the * provisions set forth hereunder. * * Provided that, if you use the AXIS OpenBT Stack with other files, * that do not implement functionality as specified in the Bluetooth * System specification, to produce an executable, this does not by * itself cause the resulting executable to be covered by the GNU * General Public License. Your use of that executable is in no way * restricted on account of using the AXIS OpenBT Stack code with it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the provisions of the GNU * General Public License. * * $Id: bt_vendor.c,v 1.31 2001/10/16 15:02:20 pkj Exp $ * */ #include <stdio.h>#include <unistd.h>#include <termios.h>#include <syslog.h>#include <sys/ioctl.h>#include <sys/types.h>#include <signal.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include <errno.h>#include "bt_misc.h"#include "bt_vendor.h"#include "bt_if.h"#define D(x) //xstatic void csr_init_phys(int fd, int flow_control);static void csr_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void digianswer_init_phys(int fd, int flow_control);static void digianswer_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void ericsson_init_phys(int fd, int flow_control);static void ericsson_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void infineon_init_phys(int fd, int flow_control);static void infineon_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void usb_init_phys(int fd, int flow_control);static void usb_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void generic_init_phys(int fd, int flow_control);static void generic_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void no_init_phys(int fd, int flow_control);static void no_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void unknown_init_phys(int fd, int flow_control);static void unknown_init_hw(int bt_cfd, int phys_fd, const char *speedstr);static void csr_change_if(int bt_cfd, int phys_fd, const char *speedstr, int flow_control);static int csr_set_max_power(int bt_cfd, short max_power);voidinit_phys(int fd, int flow_control){ switch (hw_vendor()) { case HW_CSR: csr_init_phys(fd, flow_control); break; case HW_DIGIANSWER: digianswer_init_phys(fd, flow_control); break; case HW_ERICSSON: ericsson_init_phys(fd, flow_control); break; case HW_INFINEON: infineon_init_phys(fd, flow_control); break; case HW_USB: usb_init_phys(fd, flow_control); break; case HW_GENERIC: generic_init_phys(fd, flow_control); break; case HW_NO_INIT: no_init_phys(fd, flow_control); break; case HW_UNKNOWN: default: unknown_init_phys(fd, flow_control); break; }}voidinit_hw(int bt_cfd, int phys_fd, const char *speedstr){ switch (hw_vendor()) { case HW_CSR: csr_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_DIGIANSWER: digianswer_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_ERICSSON: ericsson_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_INFINEON: infineon_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_USB: usb_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_GENERIC: generic_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_NO_INIT: no_init_hw(bt_cfd, phys_fd, speedstr); break; case HW_UNKNOWN: default: unknown_init_hw(bt_cfd, phys_fd, speedstr); break; }}intbt_set_max_power(int bt_cfd, short max_power){ switch (hw_vendor()) { case HW_CSR: return csr_set_max_power(bt_cfd, max_power); default: errno = EPERM; return -1; }}/* * This function tries to recover stack if init failed * For now all other vendors but CSR is left to restart * btd but later on auto_probe on baudrate could be done. */voidinit_failed(int bt_cfd, int phys_fd, const char *speedstr, int flow_control){ static int did_restart = 0; /* only try once */ if (did_restart) { syslog(LOG_INFO, "Init failed after second try, giving up..."); exit(1); } sleep(1); switch (hw_vendor()) { case HW_CSR: /* Try changing interface BCSP<->H4 */ csr_change_if(bt_cfd, phys_fd, speedstr, flow_control); did_restart = 1; /* Restart btd */ kill(getpid(), SIGUSR1); break; default: /* Restart btd */ syslog(LOG_INFO, "Init failed, lets try restarting btd"); did_restart = 1; /* Restart btd */ kill(getpid(), SIGUSR1); break; }}inthw_vendor(void){ static int hw_vendor = HW_NOT_PROBED; if (hw_vendor == HW_NOT_PROBED) { char *vendor = bt_hw_vendor(); if (!vendor) hw_vendor = HW_UNKNOWN; else if (!strcmp(vendor, "CSR")) hw_vendor = HW_CSR; else if (!strcmp(vendor, "Digianswer")) hw_vendor = HW_DIGIANSWER; else if (!strcmp(vendor, "Ericsson")) hw_vendor = HW_ERICSSON; else if (!strcmp(vendor, "Infineon")) hw_vendor = HW_INFINEON; else if (!strcmp(vendor, "USB")) hw_vendor = HW_USB; else if (!strcmp(vendor, "Generic")) hw_vendor = HW_GENERIC; else if (!strcmp(vendor, "No Init")) hw_vendor = HW_NO_INIT; else hw_vendor = HW_UNKNOWN; } return hw_vendor;}/* ===============================================================*//* CSR specific commands *//* ===============================================================*/#define PSKEY_LC_MAX_TX_POWER 0x0017#define PSKEY_HOSTIO_UART_PS_BLOCK 0x0191#define PSKEY_HOST_INTERFACE 0x01f9#define PSKEY_UART_SLEEP_TIMEOUT 0x0222#define CSR_PSKEY_GETREQ 0x0#define CSR_PSKEY_SETREQ 0x2/* Set the phys device to CSR default, 115200 */ voidcsr_init_phys(int fd, int flow_control){ D(syslog(LOG_INFO, "Setting default speed 115200")); fd_setup(fd, "115200", flow_control);}/* * Read/Write any PS key in CSR module * ps_vals holds return values / set params depending on * type of operation */void csr_pskey(int bt_cfd, unsigned short ps_key, unsigned short rw_mode, unsigned short *ps_vals, unsigned short n_pars){ unsigned short msg[CSR_PSKEY_MAXPARAMS + CSR_PSKEY_MSGHDR_SIZE]; syslog(LOG_INFO, __FUNCTION__": ps_key 0x%x rw_mode : %d", ps_key, rw_mode); msg[0] = ps_key; msg[1] = rw_mode; msg[2] = n_pars; if (n_pars > CSR_PSKEY_MAXPARAMS) { syslog(LOG_INFO, __FUNCTION__ ": Error: Max nbr pskey params is %d [%d]", CSR_PSKEY_MAXPARAMS, n_pars); return; } if (rw_mode == CSR_PSKEY_GETREQ) memset(&msg[CSR_PSKEY_MSGHDR_SIZE], 0, n_pars*2); /* GETREQ */ else memcpy(&msg[CSR_PSKEY_MSGHDR_SIZE], ps_vals, n_pars*2); if (ioctl(bt_cfd, BT_CSR_PSKEY, msg) < 0) { perror(__FUNCTION__); exit(1); } /* Copy back return params if READ (skip message header) */ if (rw_mode == CSR_PSKEY_GETREQ) memcpy(ps_vals, &msg[CSR_PSKEY_MSGHDR_SIZE], n_pars*2);}int csr_disable_deep_sleep(int bt_cfd){ unsigned short ps_parbuf; /* Make sure uart deep sleep is disabled when using BCSP */ csr_pskey(bt_cfd, PSKEY_UART_SLEEP_TIMEOUT, CSR_PSKEY_GETREQ, &ps_parbuf, 1); if (ps_parbuf != 0) { syslog(LOG_INFO, "Disabling deep sleep timer"); ps_parbuf = 0; /* disable deep sleep timer */ csr_pskey(bt_cfd, PSKEY_UART_SLEEP_TIMEOUT, CSR_PSKEY_SETREQ, &ps_parbuf, 1); return 1; } return 0;}/* * Switches host interface in CSR HW (H4<->BCSP) */void csr_change_if(int bt_cfd, int phys_fd, const char *speedstr, int flow_control){ /* This may seem reversed, but hw_vendor() returns what we want, not what we have, in this situation... */ if (!bt_bcsp_mode(bt_cfd, -1)) { csr_bcsp_to_h4(bt_cfd, phys_fd, speedstr, flow_control); } else { csr_h4_to_bcsp(bt_cfd, phys_fd, speedstr, flow_control); }}void csr_bcsp_to_h4(int bt_cfd, int phys_fd, const char *speedstr, int flow_control){ unsigned short ps_parbuf[10]; syslog(LOG_INFO, "Changing CSR host IF: BCSP -> H4"); /* Temporarily set stack to use BCSP framing */ bt_bcsp_mode(bt_cfd, 1); if (speedstr) fd_setup(phys_fd, speedstr, flow_control); else init_phys(phys_fd, flow_control); reset_hw(); if (ioctl(bt_cfd, BTINITBCSP) < 0) { perror(__FUNCTION__); exit(1); } sleep(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -