📄 bt_misc.c
字号:
/* * bt_misc.c -- Miscellaneous functions used with BT 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: bt_misc.c,v 1.23 2001/10/16 15:02:19 pkj Exp $ * */#include <sys/types.h>#include <sys/ioctl.h>#include <sys/wait.h>#include <fcntl.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 <linux/serial.h> /* struct serial_struct *//* 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>#include "btd.h"#include "bt_misc.h"#include "bt_if.h"#define D(x) //xintwrite_pidfile(const char *pidname){ int pid_fd; char pid_buf[80]; if ((pid_fd = open(pidname, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666)) < 0) { if (errno == EEXIST) { syslog(LOG_INFO, "There is already another version of %s running.", pidname); } else { syslog(LOG_INFO, "Could not create pid file for btinit."); } exit(0); } sprintf(pid_buf, "%d\n", getpid()); write(pid_fd, pid_buf, strlen(pid_buf)); close(pid_fd); return pid_fd;}intrestart_btd(void){ int fd; int pid = -1; int size; char buf[100]; if ((fd = open("/var/run/btd.pid", O_RDONLY)) < 0) { return -1; } if ((size = read(fd, buf, sizeof buf - 1)) > 0) { buf[size-1] = '\0'; pid = atoi(buf); } close(fd); if (pid > 0) { kill(pid, SIGUSR1); return 0; } return -1;}/* Local UNIX socket */intopen_socket(const char *name, int role){ struct sockaddr_un server_address; int fd; D(syslog(LOG_INFO, "Opening socket %s", name)); if (role == SERVER) { /* remove any old socket */ unlink(name); } if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to create %s", name); return -1; } memset(&server_address, 0, sizeof server_address); server_address.sun_family = AF_UNIX; strcpy(server_address.sun_path, name); if (role == SERVER) { int tmp_fd; if (bind(fd, (struct sockaddr *)&server_address, sizeof server_address) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to bind %s", name); close(fd); return -1; } if (listen(fd, 5) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to listen on %s", name); close(fd); return -1; } if ((tmp_fd = accept(fd, NULL, NULL)) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to accept %s", name); close(fd); return -1; } close(fd); fd = tmp_fd; } else { if (connect(fd, (struct sockaddr *)&server_address, sizeof server_address) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to connect %s", name); close(fd); return -1; } } D(syslog(LOG_INFO, "Socket connected to %s", name)); return fd;}/* TCP socket */intopen_tcpsocket(const char *addrstr, int role){ struct sockaddr_in server_address; int fd; int port; char ipstr[16]; char *pos; /* parse address string */ if (!(pos = strchr(addrstr, ':'))) { fprintf(stderr, "Port argument missing!\n"); return -1; } /* copy ip address */ *pos = '\0'; strncpy(ipstr, addrstr, sizeof ipstr); ipstr[sizeof ipstr - 1] = '\0'; /* extract port number */ port = atoi(pos+1); /* open socket */ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to create socket"); return -1; } memset(&server_address, 0, sizeof server_address); server_address.sin_family = AF_INET; server_address.sin_port = htons(port); if (role == SERVER) { int tmp_fd; server_address.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(fd, (struct sockaddr *)&server_address, sizeof server_address) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to bind to port %d", port); close(fd); return -1; } if (listen(fd, 5) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to listen to port %d", port); close(fd); return -1; } D(syslog(LOG_INFO, "Waiting for connection on port %d", port)); /* request for a new connection */ if ((tmp_fd = accept(fd, NULL, NULL)) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to accept on port %d", port); close(fd); return -1; } close(fd); fd = tmp_fd; } else { D(syslog(LOG_INFO, "Connecting to %s:%d", ipstr, port)); /* destination address */ server_address.sin_addr.s_addr = inet_addr(ipstr); if (connect(fd, (struct sockaddr *)&server_address, sizeof server_address) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to connect to %s:%d", ipstr, port); close(fd); return -1; } } return fd;}/* * Retrieve the numerical IP address of eth0 for now. */char *get_local_ip_address(void){ int fd; struct ifreq ifr; static char ip[20]; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { syslog(LOG_ERR, __FUNCTION__ ": Failed to create socket"); return "0.0.0.0"; } ifr.ifr_addr.sa_family = AF_INET; strcpy(ifr.ifr_name, "eth0"); if (ioctl(fd, SIOCGIFADDR, (int)&ifr) < 0) { syslog(LOG_INFO, __FUNCTION__ ": Could not determine local IP address!"); close(fd); return "0.0.0.0"; } close(fd); strcpy(ip, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); return ip;}int translate_speed(int spd){ int speed_c = 0; switch (spd) { case 9600: speed_c = B9600; break; case 19200: speed_c = B19200; break; case 38400: speed_c = B38400; break; case 57600: speed_c = B57600; break; case 115200: speed_c = B115200; break;#ifdef B230400 case 230400: speed_c = B230400; break;#endif#ifdef B460800 case 460800: speed_c = B460800; break;#endif#ifdef B921600 case 921600: speed_c = B921600; break;#endif default: printf("Bad baudrate %d.\n", spd); break; } return speed_c;}voidfd_setup(int fd, const char *speedstr, int flow){ struct termios t; const char *divisorp; unsigned long divisor = 0; unsigned long baudbase = atol(speedstr); unsigned long speed = baudbase; struct serial_struct serial; int got_serial = 0; if (fd < 0) { perror("fd_setup"); exit(1); } /* speedstr is either "baudrate" or "baud_base/divisor", * if there is a '/' we should use serial_struct and set * baud_base and custom_divisor etc. */ divisorp = strchr(speedstr, '/'); if (divisorp) { divisor = atol(divisorp+1); if (!divisor) /* Just to be safe */ { divisor = 1; } } if (tcgetattr(fd, &t) < 0) { perror("tcgetattr"); exit(1); } if (ioctl(fd, TIOCGSERIAL, &serial) >= 0) { got_serial = 1; if (divisor) { serial.baud_base = baudbase; serial.custom_divisor = divisor; serial.flags |= ASYNC_SPD_CUST; speed = 38400; } else { /* Remove special baudrate */ serial.flags &= ~ASYNC_SPD_CUST; } } else if (divisor) { perror("Error getting serial_struct with TIOCGSERIAL"); exit(1); } cfmakeraw(&t); t.c_cflag &= ~CBAUD; if (bt_bcsp_mode(-1, -1)) { flow = 0; t.c_cflag |= translate_speed(speed) | CS8 | CLOCAL | PARENB; t.c_cflag &= ~PARODD; } else { t.c_cflag |= translate_speed(speed) | CS8 | CLOCAL; } t.c_oflag = 0; /* turn off output processing */ t.c_lflag = 0; /* no local modes */ if (flow == USE_FLOW_CTRL) t.c_cflag |= CRTSCTS; else if (flow == USE_NO_FLOW) t.c_cflag &= ~CRTSCTS; if (tcsetattr(fd, TCSANOW, &t) < 0) { perror("fd_setup : tcsetattr"); exit(1); } if (got_serial && ioctl(fd, TIOCSSERIAL, &serial) < 0) { perror("Error setting serial_struct with TIOCSSERIAL"); }}unsigned longspeedstrtoli(const char *speedstr){ unsigned long baudbase = atol(speedstr); unsigned char *divisorp = strchr(speedstr, '/'); unsigned long divisor = 1; if (divisorp) { divisor = atol(divisorp+1); if (!divisor) /* Just to be safe */ { divisor = 1; } } return baudbase/divisor;}const char*bd2str(const unsigned char *bd){ static char buf[20]; sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", bd[0], bd[1], bd[2], bd[3], bd[4], bd[5]); return buf;}#ifndef BT_USERSTACKvoid print_data(const char *message, const unsigned char *buf, int len){ int t = 0; if (message) { printf("\n%s (%d):\n", message, len); } while (t < len) { printf("0x%02x ", (uint)buf[t++]); if (!(t % 16)) printf("\n"); } if (t && (t % 16)) { printf("\n"); }}#endif/* Sets pin code to string pin, disabled if using 'disable' as pin */voidset_pin_code(const char *pin){#ifdef __CRIS__ char exec_pinstr[100]; if (strcmp(pin, "disable") == 0) { printf("Disable PIN usage\n"); system("/bin/parhandclient -nosync set root.Security.UseLANSecurity no sync"); return; } /* Set pinconde */ system("/bin/parhandclient -nosync set root.Security.UseLANSecurity yes"); sprintf(exec_pinstr, "/bin/parhandclient -nosync set root.Security.PINCode %s sync", pin); system(exec_pinstr);#else printf("set_pin_code not implemented [%s, line %d]\n", __FILE__, __LINE__);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -