📄 btd.c
字号:
/* * btd.c -- Control application for AXIS Bluetooth stack * * 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: btd.c,v 1.105 2001/10/21 10:33:10 pkj Exp $ * */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* syntax: ./btd [options] options: -u, --physdev <uart device> sets which uart device that will be used by the stack default: ttyS2 -b, --btdev <bluetooth device> sets which bluetooth device that will be used from application default: ttyBT0 -d, --local <local ip> Sets local ipadress in pppd options -D, --remote <remote ip> Sets remote ipaddress in pppd options -e, --modem Use modem emulation (used when emulate modem in windows dialup. Can also be done from command line mode. default: on -m, --cmdmode enters command line mode default: skip command line mode -n, --local-name prefix used for the local bluetooth device name default: nothing "-r server", --server sets application role to server "-r client", --client sets application role to client) default: server -R, --reset reset bluetooth hardware before use default: no reset -s, --speed <speed> sets uart speed 9600, 19200, 38400, 57600, 115200, 230400, 460800 default: 115200 baud -S, --unixsock use local unix socket as phys device Used together with hci emulation to test stack locally (usermode stack only) -T, --tcpsock <ipaddr:port> use tcp socket as phys device. Used together with hci emulation to test stack over any TCP/IP based network Server listens on <:port>, client tries to connect to <ipaddr:port>. (usermode stack only) e.g if using module at 460800 baud and acting server ./btd --speed 460800 if acting as a client with a command line interface ./btd -r client if using non default devices ./btd --physdev /dev/ttyS2 --btdev /dev/ttyBT3 [options...] if using the stack in usermode over a local UNIX socket. Do the following in separate windows Server : ./btd --cmdmode --unixsock Client : ./btd --cmdmode --unixsock --client if using the stack in usermode over a TCP socket. Do the following on separate computers connected to the same network Server : ./btd --cmdmode --tcpsock <:port> Client : ./btd --cmdmode --tcpsocket <ipaddr:port> --client*//* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include <sys/time.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/wait.h>#include <fcntl.h>#include <time.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <termios.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <errno.h>#include <stdarg.h>#include <signal.h>#include <getopt.h>/* The following includes are required to be able to determine the local * address by examining eth0 */#include <sys/socket.h>#include <net/if.h>#include <netinet/in.h>#include <sys/un.h>#include <arpa/inet.h>#if defined(HAVE_READLINE_READLINE)#include <readline/readline.h>#include <readline/history.h>#elif defined(HAVE_READLINE)#include <readline.h>#include <history.h>#endif#define RESTART_ENABLED#define USE_IPASSIGN/* automatic restart of application after a hw reset */#ifdef RESTART_ENABLED#include <setjmp.h> #endif/* USER SPACE STACK TEST *//* defined in Makefile */#ifdef BTD_USERSTACK#define USE_PSEUDOTERMINALS /* remove ? */#include <pty.h>#include <pthread.h>#include "include/btcommon.h"#include "include/btmem.h"#include "include/hci.h"#include "include/l2cap.h"#include "include/l2cap_con.h"#include "include/sdp.h"#include "include/tcs.h"#include "include/test.h"#include "include/rfcomm.h"#include "include/btdebug.h"#include "include/bt_proc.h"#include "include/unplug_test.h"/* * Local functions */ static int init_read_thread(void);static void hci_receive_thread(void);int open_pty(void);static int init_pty_thread(void);static void pty_receive_thread(void);const char* psmname(unsigned short psm);int bt_write_lower_driver(unsigned char *data, int len);int bt_write_top(char *buf, int count, int line);int bt_receive_top(unsigned int con_id, unsigned char *data, int len);void bt_rfcomm_connection_ready(int status);void bt_sdp_connection_ready(int status);int bt_initiated(void);int bt_use_bcsp(int new_use_bcsp);int bt_dfu_mode(int new_dfu_mode);extern int bt_read_proc(char *buf, int len);bt_stat_struct bt_stat;static int bt_initdone = 0;rfcomm_con *test_rfcomm;int test_dlci;#ifdef USE_PSEUDOTERMINALSstatic int pty_master_fd;static int pty_slave_fd;/* pty device name */char ptydev[256];pthread_t pty_thread;#endif /* USE_PSEUDOTERMINALS *//* thread used to read data on "physical" device */pthread_t read_thread;#if BT_DATA_DEBUG#define BT_DATA(fmt...) printf("BT DATA "fmt)#else#define BT_DATA(fmt...) #endif#if BT_DATADUMP_DEBUG#define PRINTPKT(str, data, len) print_data(str, data, len)#else#define PRINTPKT(str, data, len)#endif/* * Socket stuff, used to run two instances of the stack on the same computer * against each other */ /* local UNIX socket */int use_local_socket = 0; /* default */#define SOCKET_NAME "/tmp/bt_server" int use_tcp_socket = 0; /* default */char *tcp_address; /* ip address and port string argument *//* returns fd to socket */static int open_tcpsocket(char *addrstr, int role);#else /* standard mode using kernel stack *//* ioctls defines etc */#include "btd.h"static int bt_disc = N_BT;#endif /* BTD_USERSTACK *//* * Local functions common to both userstack and standard btd */static int open_device(char* dev, int flags, int role);static void close_device(int fd);static void fd_setup(int fd, int speed, int flow);static int translate_speed(int spd);static void init_phys(int fd);static void init_stack(int spd);static void shutdown_stack(void);static void init_hw(int spd);static int process_cmd(char *buf, int bt_fd);static char* get_local_addr(void);static void start_pppd(void);static void build_pppdopt(int role);static void btd_cleanup(void);static void btd_killchilds(void);static void btd_sighandler(int sig);static void init_sighandler(void);static int open_socket(char *name, int role);static int sdpsrv_pid = 0;static int start_sdp_server(void);/* misc */#ifndef BTD_USERSTACKstatic void set_bt_line_disc(int phys_fd, int bt_disc, char* physdev);#endifstatic void bt_connect(int bt_fd, unsigned char *bd, unsigned int con_id);static void bt_disconnect(int bt_fd, unsigned int con_id);static void bt_waitline(int bt_fd, int line);static void bt_inquiry(int bt_cfd, int nbr_rsp, int t);static void bt_set_bd_addr(int bt_cfd, int* bd);static void read_local_bd(int bt_cfd, unsigned char *bd_addr);static void read_remote_bd(int bt_cfd, int line, unsigned char *bd_addr);static void role_switch(int bt_cfd, unsigned char *bd_addr, int role);#ifndef BTD_USERSTACKstatic char* bt_hw_vendor(void);#endifstatic void reset_hw(void);static void bt_set_classofdevice(int bt_fd, unsigned short service_class, unsigned char major_class, unsigned char minor_class, unsigned char format);/* Misc */static void show_menu(void);static int hw_vendor(void);static void csr_init_phys(int fd);static void csr_init_hw(int spd);static void digianswer_init_phys(int fd);static void digianswer_init_hw(int spd);static void ericsson_init_phys(int fd);static void ericsson_init_hw(int spd);static void infineon_init_phys(int fd);static void infineon_init_hw(int spd);static void usb_init_phys(int fd);static void usb_init_hw(int spd);static void generic_init_phys(int fd);static void generic_init_hw(int spd);static void no_init_phys(int fd);static void no_init_hw(int spd);static void unknown_init_phys(int fd);static void unknown_init_hw(int spd);#undef ECS_TEST_FUNCTIONS#ifdef ECS_TEST_FUNCTIONSstatic void enable_dut(int bt_cfd);static void test_connection_req(int* bd);/* ericsson test functions, will be moved to specific test program leater */static void ericsson_test_control(int* tmp);static void ericsson_enter_test_mode(int* tmp);static void ericsson_tx_test(int* tmp);#define ERICSSON_ENTER_TEST_MODE 0x11#define ERICSSON_TEST_CONTROL 0x12#define ERICSSON_TX_TEST 0x19#define MANUFACTURER_SPEC 0x3f#endif#if !defined(HAVE_READLINE) && !defined(HAVE_READLINE_READLINE)void read_history(char *hist_file_name);void write_history(char *hist_file_name);void add_history(char *command);char *readline(char *promt);#endif /* Modem emulator stuff */#define CONNECT 1#define NULLCONNECT 2#define RESTART 3#define SHUTDOWN 4#define HELLOCONNECT 5#define DO_PPP 6#define SEND_OK 7#define PPP_DELIMITER 0x7e#define PPP_PROT_LCP 0xc021#define PPP_TERM_REQ 0x5static int parse_modem_data(char *databuf, int len, int bt_fd);static void modem_emulator(int bt_fd, char *data, int len);#ifdef PALM_FIXstatic int search_str(char *data, const char *searchstr);#endif/* * Some defines */#define PID_FILE "/var/run/btd.pid"#define PPPDCMD "pppd"#ifdef BTD_USERSTACK#define SDPSRV_CMD "sdp_user"#else#define SDPSRV_CMD "sdp_server"#endif#define BT_CTRL_TTY "/dev/ttyBTC"/* default settings */#define CLIENT 0#define SERVER 1#ifdef __CRIS__#define DEFAULT_PHYS_DEV "/dev/ttyBT"#define DEFAULT_SPEED "460800"#else#define DEFAULT_PHYS_DEV "/dev/ttyS0"#define DEFAULT_SPEED "115200"#endif#define DEFAULT_BT_DEV "/dev/ttyBT0"#define DEFAULT_ROLE SERVER#define USE_NO_FLOW 0 #define USE_FLOW_CTRL 1#define START_PPP 1#define QUIT_BTD 2#define LOCAL_NAME_LENGTH 32#define HOST_NAME_LENGTH 100#define DOMAIN_NAME_LENGTH 100#define BTD_HISTORY_FILE "/tmp/btd_history"#define HW_NOT_PROBED -1#define HW_CSR 0#define HW_DIGIANSWER 1#define HW_ERICSSON 2#define HW_INFINEON 3#define HW_USB 4#define HW_GENERIC 5#define HW_NO_INIT 6#define HW_UNKNOWN 7/* Bluetooth discipline define. Should reside in /include/asm/termios.h However, if compiling this standalone simply use the define in bluetooth.h */ static int pid_fd = -1;static int phys_fd = -1;static int bt_fd = -1;static int bt_cfd = -1;static char* physdev = DEFAULT_PHYS_DEV;static char* btdev = DEFAULT_BT_DEV;static int hw_init = 1;static char* speedstring = DEFAULT_SPEED;static int modem_emulation = 1;static int modem_connected = 0;static int enter_cmd_mode = 0;static int role = DEFAULT_ROLE;static int do_reset = 0;static int start_ppp = 1;static int pppd_pid = 0;static char *pppd_options[32];static char local_bd_string[18];static char remote_bd_string[18];static char local_name[LOCAL_NAME_LENGTH+1];static int btd_shuttingdown = 0;/* used to know in modem emulator whether to restart or exit */#ifdef USE_IPASSIGN/* IP assign stuff */enum ipa_requests{ GETCLIENTIP, GETDNSSERVERS, RETURNCLIENTIP};typedef struct ipa_client{ struct in_addr ip; /* Returns IP address for the client */ struct in_addr dns[2]; /* Returned DNS servers */ int nbr_of_dns; /* Returns number of found DNS servers. */ struct in_addr wins[2]; /* Returned MS WINS servers */ int nbr_of_wins; /* Returns number of found MS WINS servers. */ struct in_addr netmask; /* Returns the netmask to be used(clients)*/ int proxyarp; /* Returns 1 if proxyarp will be used */ int useradius; /* Returns 1 if RADIUS is being used */ int useradiusip; /* Returns 1 if IP address assignment via * RADIUS is allowed */ int usingmasq; /* Returns 1 if NAT is being used */}ipa_client;typedef struct ipa_request{ unsigned short type; /* type of request */ unsigned char remote_bd[6]; /* Requestors BD address */ struct ipa_client client; /* return client */} ipa_request;#define SRVSOCKET "/tmp/ipa_server"int ipa_sock = -1;static char ipa_buf[128];struct ipa_client *ipa_send(ipa_request *req);static void ipa_getpars(void);static struct ipa_request ipa_req;static struct ipa_client a_client;#endif/* Locals used for IP settings to pppd */char ip_addresses[35]; /* Max length 255.255.255.255:255.255.255.255 */char *local_address = NULL;char *remote_address = NULL;char *ppp_netmask = NULL;static char *prim_dns = NULL;static char *sec_dns = NULL;static char *prim_wins = NULL;static char *sec_wins = NULL;static int use_proxyarp = 1;static int use_radius = 0;static int using_masq = 0;static int use_radius_ip_assign = 0;static int use_ipassign = 0;#ifdef RESTART_ENABLEDsigjmp_buf jmpbuffer;#endifstatic int option_index = 0;/* long option list */static struct option long_options[] ={ {"physdev", 1, NULL, 'u'}, /* phys device used from stack */ {"btdev", 1, NULL, 'b'}, /* bluetooth device */ {"client", 0, &role, CLIENT}, {"server", 0, &role, SERVER}, {"speed", 1, NULL, 's'}, /* uart speed towards hw */ {"local-name", 1, NULL, 'n'}, /* set local bluetooth name */ {"local", 1, 0, 'd'}, /* set local ip address */ {"remote", 1, 0, 'D'}, /* set remote ip address */ {"modem", 1, NULL, 'e'}, /* modem emulation */ {"reset", 0, &do_reset, 1}, /* reset BT HW */ {"cmdmode", 0, &enter_cmd_mode, 1}, /* enter command line mode */ {"tcpsock", 1, 0, 'T'}, /* use network socket*/ {"unixsock", 0, 0, 'S'}, /* use local socket */ {"radius", 0, &use_radius, 1}, /* enable radius */ {0, 0, 0, 0}};char* menu[] ={ "\nMenu", "------------------------", " inq <Max number of responses> (inquiry scan) ", " rf_conn <xx:xx:xx:xx:xx:xx> <srv ch> <line>", " rf_send <nbr bytes> <nbr repeats> <line>", " rf_disc <line>", " rf_wait <line>", /* waits for a connection on that line */ " me <1/0>", /* modem emulation */ " setbd <xx:xx:xx:xx:xx:xx>", /* only ericsson HW */ " readbd", /* read module bd address */ " reset", /* reset board */ " role_switch <xx:xx:xx:xx:xx:xx> <role> (0=master, 1=slave)",#ifdef BTD_USERSTACK " stat ", /* similar to reading the /proc/bt */#endif#ifdef ECS_TEST_FUNCTIONS " ecs_entertest <handle> (hex)", " ecs_testctrl <par1,par2,...,par9> (hex)", " ecs_txtest <par1,par2,...,par11> (hex)", " ecs_testcon <xx:xx:xx:xx:xx:xx> (hex)", " enable_dut", /* enable device under test mode */#endif " ppp", " quit",#ifdef BTD_USERSTACK "", "--- Test commands ------",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -