⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btd.c

📁 bluetooth 驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * btd.c --   Control application for AXIS Open BT stack * *          o Responsible for control of physical transport layer (UART), *          o Initializing/shutdown of stack incl SDP server database *          o Handles multipoint ppp connections *          o Handles HW upgrade * * 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.32 2001/10/16 15:02:20 pkj Exp $ * *//* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Syntax:  ./btdm [options]options: 	-u, --physdev <uart device>	Sets which uart device that will be used by the stack	default: ttyS0	-m, --modem-emul <1/0>	Use modem emulation (used when emulate modem in windows dialup. 	Can also be done from command line mode. 	default: on	-n, --local-name <prefix>	prefix used for the local bluetooth device name	default: nothing	-R, --reset	reset bluetooth hardware before use	default: no reset	-i, --initial-speed <speed | baudbase/divisor>	sets initial uart speed	default: 115200 baud	-s, --speed <speed | baudbase/divisor>	sets uart speed	9600, 19200, 38400, 57600, 115200, 230400, 460800	default: 115200 baud                 	-f, --noflow	force uart communication to not use CTS and RTS	default: flow control activated if defined hardware support it	e.g  	./btdm --reset --speed 460800 --physdev /dev/ttyS0 --local-name OpenBT  	./btdm --reset --speed 1000000/1 --physdev /dev/ttyS0 --local-name OpenBT- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <signal.h>#include <syslog.h>#include <getopt.h>#include <setjmp.h>#include <termios.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sys/wait.h>#include <arpa/inet.h>#include "btd.h"#include "bt_conf.h"#include "bt_vendor.h"#include "bt_misc.h"#include "bt_if.h"#include "bt_ipa.h"#define D(x) //x/* ========================================================== *//* PPPD stuff */#define NOCONNECTION 0#define CONNECTED 1#define WAITING_PPPCONF 2 #define PPPCONF_DONE 3#define MODEM_STARTED 4#define PPPD_STARTED 5#define WAITING_RETURN_PPPCONF 6typedef struct peer_struct{  int state;  int pppd_pid;  int do_modememul;  unsigned char remote_bd[6];  struct ip_set *ipset;} peer_struct;struct peer_struct peerlist[BT_NBR_DATAPORTS];struct ip_set ipsetlist[BT_NBR_DATAPORTS];static unsigned char dev[20];static unsigned char ip_addresses[35];static unsigned char ms_dns1[35];static unsigned char ms_dns2[35];static unsigned char ms_wins1[35];static unsigned char ms_wins2[35];static unsigned char netmask[35];static char remote_bd_str[18];static char local_bd_str[18];static fd_set rfd;static struct timeval tv;#define PEER(line) (peerlist[line])#define IPSET(line) (ipsetlist[line])#define STATE(line) (peerlist[line].state)static unsigned char *pppd_options[32];/* ========================================================== *//* IPA stuff */static int ipa_fd = -1;static struct ipa_msg *msg;static unsigned char ipa_buf[256];static int parse_ipa_response(struct ipa_msg *msg);static int ipa_sendrequest(int line, unsigned char *bd,			   unsigned short type);/* ========================================================== *//* General BTD stuff */#define PID_FILE "/var/run/btd.pid"#define MODEMEMULCMD "memul" /* change name !*/#define PPPDCMD "pppd"static int do_hwinit = 1; /* do vendor specific initialization */static int do_reset = 0;  /* reset hw using I/O pins */static int modem_emul = 1;    /* default modem emulation is enabled */static char *init_hw_speedstr = NULL; /* not set */static int flow_control = USE_FLOW_CTRL;static char *physdev = DEFAULT_PHYS_DEV;static char *speedstr = DEFAULT_SPEED;static char local_name[LOCAL_NAME_LENGTH+1]; /* 'friendly' name in HW module */static int btd_pid = -1;static int sdpsrv_pid = 0;static int bt_cfd = -1;   /* control tty for bt stack */static int phys_fd = -1;  /* physical device e.g ttyS0 */static sigjmp_buf jmpbuffer; /* used to jump back in program after doing reset *//* long option list */static struct option long_options[] ={  { "noflow",        1, NULL, 'f' },      /* do not use flow control */  { "initial-speed", 1, NULL, 'i' },      /* initial uart speed */  { "physdev",       1, NULL, 'u' },      /* phys device used from stack */  { "modem-emul",    1, NULL, 'm' },  { "local-name",    1, NULL, 'n' },      /* set local bluetooth name */  { "reset",         0, NULL, 'R' },      /* reset BT HW */  { "speed",         1, NULL, 's' },      /* uart speed towards hw */  { 0, 0, 0, 0 }};static int option_index = 0;static void init();static void init_sighandler(void);static void btd_cleanup(void);static void btd_killchilds(void);static void sighandler(int sig);static void discover_connections(int bt_cfd);static void build_pppdopts(int line, char **opts);static int start_pppd(int line, char *speedstr, char **opts);/* ========================================================== */intmain(int argc, char **argv){    int result, opt;  int bt_disc = N_BT;    syslog(LOG_INFO, "Bluetooth daemon starting");    if (atexit(btd_cleanup) < 0)  {    printf("btd failed to register cleanup function.\n");    exit(1);   }    /* now parse options */  while ((opt = getopt_long(argc, argv, "fi:m:nRs:u:",			    long_options, &option_index)) != -1)  {    switch(opt)    {     case 'f':      /* do not use flow control */      flow_control = USE_NO_FLOW;      D(syslog(LOG_INFO, "no flow control"));      break;     case 'i':      /* uart device */      init_hw_speedstr = optarg;      D(syslog(LOG_INFO, "init_hw_speed %s baud", init_hw_speedstr));      break;     case 'm':      /* uart device */       modem_emul = atoi(optarg);      break;           case 'n':      D(syslog(LOG_INFO, "setting local name to %s", optarg));      strncpy(local_name, optarg, LOCAL_NAME_LENGTH);      local_name[LOCAL_NAME_LENGTH] = '\0';      break;           case 'R':      /* try to reset the hardware */      D(syslog(LOG_INFO, "reset HW"));      do_reset = 1;      break;           case 's':      /* speed */      D(syslog(LOG_INFO, "phys dev running at %s", optarg));      speedstr = optarg;      break;           case 'u':      /* uart device */      D(syslog(LOG_INFO, "phys dev: %s", optarg));      physdev = optarg;      break;     default:      break;    }  }  /* Set restart point */  if (sigsetjmp(jmpbuffer, 1) != 0)  {    syslog(LOG_INFO, "Restart...");    sleep(1);  }        init();  if ((phys_fd = open(physdev, O_RDWR | O_NOCTTY)) < 0)  {    perror("Could not open phys dev");    exit(1);  }  /* Sets initial HW baudrate */  if (init_hw_speedstr != NULL)    fd_setup(phys_fd, init_hw_speedstr, flow_control);  else    init_phys(phys_fd, flow_control);  /* Set the current tty to the bluetooth discpline */  set_bt_line_disc(phys_fd, bt_disc, physdev);  bt_cfd = bt_openctrl();  tcflush(phys_fd, TCIOFLUSH);  /* Hardreset of BT hardware */  if (do_reset)    reset_hw();  if (init_stack(bt_cfd) < 0)  {    /* For some reason, the stack sometimes fails to initialize the first       time. So let us try an extra time, just to be sure... */    if (init_stack(bt_cfd) < 0)    {      init_failed(bt_cfd, phys_fd, init_hw_speedstr, flow_control);    }  }  if (do_hwinit)    init_hw(bt_cfd, phys_fd, speedstr);    /* All initialized and ready to accept connections */    while (1)  {    tv.tv_sec = 0;    tv.tv_usec = 500000;    FD_ZERO(&rfd);      if (ipa_fd >= 0)      FD_SET(ipa_fd, &rfd);        result = select(FD_SETSIZE, &rfd, NULL, NULL, &tv);    switch (result)    {     case 0:      {#ifdef USE_IPASSIGN        /* Check for outstanding IPA requests */        int i = 0, waiting_iparsp = 0;        while (i < BT_NBR_DATAPORTS)        {          if ((STATE(i) == WAITING_PPPCONF) ||              (STATE(i) == WAITING_RETURN_PPPCONF))          {            D(syslog(LOG_INFO, "Waiting for IPA response"));            waiting_iparsp = 1;          }          i++;        }                if (waiting_iparsp)          break;#endif                /* Timeout, check for new rfcomm cons */        discover_connections(bt_cfd);      }      break;           case -1:      if (errno != EINTR)      {        /* Error */        perror("select");                /* FIXME -- e.g if ipa server restarts !!! */      }      break;           default:      {#ifdef USE_IPASSIGN	/* Got data on some fd */        int retval;        /* IPA response */        if (ipa_fd >= 0 && FD_ISSET(ipa_fd, &rfd))        {          msg = (struct ipa_msg*) ipa_buf;          /* Got response from IPA, if ok then start pppd or modem emul */          ipa_read(ipa_fd, msg);          if ((retval = parse_ipa_response(msg)) < 0)          {            unsigned int con_id;            int line = ((struct ipa_status*)(msg->msg))->id;            syslog(LOG_INFO, "Got IPA error %d, disconnecting line %d", retval, line);            con_id = CREATE_RFCOMM_ID(line, 0);            if (bt_disconnect(bt_cfd, con_id) < 0)            {              /* FIXME: What to do if disconnection fails */              syslog(LOG_INFO, "Disconnection failed");            }            else            {              STATE(line) = NOCONNECTION;            }          }        } #endif      }      break;    }      } /* while */} /* main */ /* Checks for new connections and starts pppd/modememulator */static void discover_connections(int bt_cfd){  int line;  D(syslog(LOG_INFO, __FUNCTION__));  for (line = 0; line < BT_NBR_DATAPORTS; line++)  {    if ((STATE(line) == NOCONNECTION) &&         bt_isconnected(bt_cfd, line))    {      syslog(LOG_INFO, "Found connection on line: %d", line);      STATE(line) = CONNECTED;            read_remote_bd(bt_cfd, line, PEER(line).remote_bd);      printf("Remote bd: %s\n", bd2str(PEER(line).remote_bd));            if (ipa_fd >= 0)      {          D(syslog(LOG_INFO, "Sending IPA request"));                PEER(line).ipset = &IPSET(line);                STATE(line) = WAITING_PPPCONF;        if (ipa_sendrequest(line, PEER(line).remote_bd, IPAREQ_GETIPSET) < 0)        {          syslog(LOG_INFO, "IPA request failed or no IPA server");                    /* Build without IPA anyway */          STATE(line) = PPPCONF_DONE;          build_pppdopts(line, (char**)pppd_options);                start_pppd(line, speedstr, (char**)pppd_options);             }        else          D(syslog(LOG_INFO, "IPA request sent"));      }      else /* No IPA server available */      {         STATE(line) = PPPCONF_DONE;        build_pppdopts(line, (char**)pppd_options);              start_pppd(line, speedstr, (char**)pppd_options);           }    }  }}/* only server */void build_pppdopts(int line, char **opts){  int i = 0;  struct ip_set *ipset = PEER(line).ipset;  char local_ip[20];    if (ipa_fd >= 0)    show_ipset(ipset, line);    D(syslog(LOG_INFO, __FUNCTION__));    sprintf(dev, "/dev/ttyBT%d",line);  /* general options */  opts[i++] = (char*)PPPDCMD;  opts[i++] = dev;  opts[i++] = speedstr;    /* move these to options file ? */  opts[i++] = "crtscts";  opts[i++] = "nopersist";  opts[i++] = "silent";  opts[i++] = "passive";    /* check if we have used IPA */  if (ipset)  {    /* FIXME -- maybe parhand can modify ppp options        file directly */        /* Use radius ? */    if (ipset->useradius)    {      unsigned char local_bd[6];            opts[i++] = "useradius";      opts[i++] = "auth";      opts[i++] = "login";      opts[i++] = "localbdaddr";      read_local_bd(bt_cfd, local_bd);              sprintf(local_bd_str, "%02x:%02x:%02x:%02x:%02x:%02x", 	      local_bd[0], 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -