📄 bt_if.c
字号:
/* * bt_if.c -- Interface functions towards kernel / userstack * * 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_if.c,v 1.41 2001/10/16 16:15:34 anderstj Exp $ * */ #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 "btd.h"#include "bt_if.h"#include "bt_vendor.h"#include "bt_misc.h"#include "bt_conf.h"#include "bt_user.h"#include "bt_errno.h"#define D(x) //x/* ============================================================= *//* Functions common for kernel and usermode stack *//* ============================================================= */int init_stack(int bt_cfd){ syslog(LOG_INFO, "Init stack");#ifndef BT_USERSTACK if (ioctl(bt_cfd, BTINITSTACK) < 0) { return -1; }#else init_userstack();#endif if (!bt_dfu_mode(bt_cfd, -1)) { /* fixme<3> -- read these parameters from config file ? */ bt_set_classofdevice(bt_cfd, 0x10, 0x3, 0x0, 0x0);#ifndef __CRIS__ set_local_hostname(bt_cfd, "AXIS");#endif } return 0;}/* ============================================================ *//* Init/shutdown and control of stack */ int bt_isinitiated(int bt_cfd){ int fd = (bt_cfd < 0 ? bt_openctrl() : bt_cfd); int stack_initiated = -1; if (fd < 0 || ioctl(fd, BTISINITIATED, &stack_initiated) < 0) { perror(__FUNCTION__); exit(1); } if (bt_cfd < 0) { close(fd); } return stack_initiated;}void shutdown_stack(int bt_cfd){ syslog(LOG_INFO, "Shutting down bluetooth stack");#ifndef BT_USERSTACK if (bt_cfd != -1 && (ioctl(bt_cfd, BTSHUTDOWN) < 0)) { syslog(LOG_ERR, "Shutting down stack failed (bt_cfd = %d)", bt_cfd); }#else if (bt_initdone) { rfcomm_close(); sdp_shutdown(); tcs_shutdown(); l2cap_shutdown(); btmem_shutdown(); bt_initdone = 0; }#endif}#ifndef BT_USERSTACKchar* bt_hw_vendor(void){ int bt_cfd = bt_openctrl(); static char buffer[20]; if (bt_cfd < 0 || ioctl(bt_cfd, BTHWVENDOR, buffer) < 0) { perror(__FUNCTION__); return NULL; } close(bt_cfd); return buffer;}#endifchar* bt_firmware_info(void){#ifndef BT_USERSTACK int bt_cfd = bt_openctrl(); static char buffer[80]; if (bt_cfd < 0 || ioctl(bt_cfd, BTFIRMWAREINFO, buffer) < 0) { perror(__FUNCTION__); return NULL; } close(bt_cfd); return buffer;#else return bt_hw_firmware();#endif}intbt_bcsp_mode(int bt_cfd, int enable){#ifndef BT_USERSTACK int fd = (bt_cfd < 0 ? bt_openctrl() : bt_cfd); if (fd < 0 || ioctl(fd, BTSETBCSPMODE, &enable) < 0) { perror(__FUNCTION__); exit(1); } if (bt_cfd < 0) { close(fd); } return enable;#else return 0;#endif}intbt_dfu_mode(int bt_cfd, int enable){#ifndef BT_USERSTACK if (ioctl(bt_cfd, BT_SET_DFU_MODE, &enable) < 0) { perror(__FUNCTION__); exit(1); } return enable;#else return 0;#endif}void reset_hw(void){#ifdef __CRIS__ int devfd; if ((devfd = bt_openctrl()) >= 0) { if (ioctl(devfd, BTRESETPHYSICALHW) < 0) { perror(__FUNCTION__); exit(1); } sleep(2); close(devfd); } else { fprintf(stderr, "ERROR! Failed to open BT control device\n"); }#else printf("Please reset HW board within 5 seconds\n"); sleep(5);#endif}int bt_openctrl(void){ int bt_cfd; D(syslog(LOG_INFO, "Now opening BT Ctrl TTY [" BT_CTRL_TTY "]"));#ifdef BT_USERSTACK printf(__FUNCTION__ ": ignored in userstack\n"); return FD_BTUSERCTRL;#else if ((bt_cfd = open(BT_CTRL_TTY, O_RDWR | O_NOCTTY)) < 0) { fprintf(stderr, "Could not open " BT_CTRL_TTY "\n"); exit(1); }#endif return bt_cfd;}/* fixme<3> -- sdp connect */intbt_connect(int bt_fd, unsigned char *bd, unsigned int con_id){ bt_connection con; int result;#ifdef BT_USERSTACK unsigned short srv_ch; unsigned short line;#endif memcpy(con.bd, bd, 6); con.id = con_id; switch(GET_PSM(con_id)) { case SDP_LAYER: case RFCOMM_LAYER: case TCS_LAYER: case L2CAP_TEST_LAYER: case L2CAP_TEST2_LAYER: case L2CAP_TEST3_LAYER: break; default: printf(__FUNCTION__" : Unknown layer\n"); con.id = 0; return -1; }#ifndef BT_USERSTACK if ((result = ioctl(bt_fd, BTCONNECT, &con))) printf("Connect failed [%s (%d)]\n", error_msg(result), MSG_GET_CODE(-result)); else printf("Connected.\n"); #else { if ((GET_PSM(con_id) == RFCOMM_LAYER) && ((con_id >> 8) & 0xff) != 0) { printf("Use line 0 instead ! (usermode only)\n"); return -1; }// printf("Connecting srv ch %d on line %d\n", srv_ch, line); result = bt_connect(bd, con_id); }#endif return result;}intbt_disconnect(int bt_fd, unsigned int con_id){ int ret_val = 0; #ifndef BT_USERSTACK if ((ret_val = ioctl(bt_fd, BTDISCONNECT, &con_id))) printf("Disconnect failed [%s (%d)]\n", error_msg(ret_val), MSG_GET_CODE(-ret_val)); else printf("Disconnected.\n");#else if ((GET_PSM(con_id) == RFCOMM_LAYER) && ((con_id >> 8) & 0xff) != 0) { printf("Use line 0 instead ! (usermode only)\n"); return -1; } ret_val = bt_disconnect(con_id);#endif return ret_val;}/* Check whether this line is lower connected in stack (rfcomm ready) */int bt_isconnected(int bt_cfd, int line){ int fd = (bt_cfd < 0 ? bt_openctrl() : bt_cfd); int ret;#ifndef BT_USERSTACK if (fd < 0 || (ret = ioctl(fd, BTISLOWERCONNECTED, &line)) < 0) { perror(__FUNCTION__); exit(1); }#else fprintf(stderr, __FUNCTION__ ": not yet implemented...\n"); ret = -1;#endif if (bt_cfd < 0) { close(fd); } return ret;}void bt_showstatus(void){#ifdef BT_USERSTACK char tmp[4096]; int len; len = bt_read_internal(tmp); tmp[len] = 0; printf(tmp);#else system("cat /proc/bt_internal");#endif }/* fixme<1> -- add usermode stack version */intbt_send(int fd, int len, int repeat){ #define MAXSIZE (4096*2) struct timeval start_t, stop_t; int bytes_tot; int avg_speed = 0; /* bps */ unsigned int ms; char tmp[MAXSIZE]; int j; if (len > MAXSIZE) { printf("Max %d bytes per write!\n", MAXSIZE); len = MAXSIZE; } bytes_tot = len*repeat; printf(__FUNCTION__ ": %d X %d bytes [%d k]\n", len, repeat, len*repeat/1000); /* fill them with letters... */ for (j = 0; j < len; j++) { tmp[j] = (j % 25) + 65; } printf("\nNow sending %d %d-bytes packet (%d kB)\n", repeat, len, bytes_tot/1000); gettimeofday(&start_t, NULL); while (repeat) { int n = 0; n = write(fd, tmp, len); if (n <= 0) { printf("couldn't write any more data...\n\n"); bytes_tot = bytes_tot-repeat*len; return -1; } repeat--; printf("%6d kB left to send... \r", ((repeat*len)/1000)); fflush(stdout); } gettimeofday(&stop_t, NULL); printf("\ndone.\n"); ms = (stop_t.tv_sec-start_t.tv_sec)*1000 + (stop_t.tv_usec-start_t.tv_usec)/1000; if (ms) avg_speed = ((8*bytes_tot)/ms); printf("Average TX rate : %d kbps (%d kB/s)\n", avg_speed, avg_speed/8); return 0;}voidbt_waitline(int bt_fd, int line){ printf("wait for a connection on line %d\n", line);#ifndef BT_USERSTACK if (ioctl(bt_fd, BTWAITFORCONNECTION, &line) < 0) { perror(__FUNCTION__); exit(1); } printf(__FUNCTION__ ": got a connection !\n");#else /* fixme<1> */ fprintf(stderr, __FUNCTION__ ": not yet implemented...\n");#endif}voidbt_waitnewconnections(int bt_fd){ printf("Wait for a new connection\n");#ifndef BT_USERSTACK if (ioctl(bt_fd, BTWAITNEWCONNECTIONS) < 0) { perror(__FUNCTION__); exit(1); } printf(__FUNCTION__ ": found a connection !\n");#else /* fixme<1>*/ fprintf(stderr, __FUNCTION__ ": not yet implemented...\n");#endif} voidbt_waitconnection(int bt_fd, int line){ printf("Wait for a connection on line %d\n", line);#ifndef BT_USERSTACK if (ioctl(bt_fd, BTWAITFORCONNECTION, &line) < 0) { perror(__FUNCTION__); exit(1); } printf(__FUNCTION__ ": got a connection !\n");#else /* fixme<1>*/ fprintf(stderr, __FUNCTION__ ": not yet implemented...\n");#endif}int bt_send_raw_hci(int bt_cfd, unsigned char *data, char len){ unsigned char buf[261]; buf[0] = len; memcpy(buf+1, data, len); print_data("data :", (char*)buf, (int)len+1);#ifndef BT_USERSTACK if (ioctl(bt_cfd, HCISENDRAWDATA, buf) < 0) { perror(__FUNCTION__); return -1; }#else fprintf(stderr, __FUNCTION__ ": not yet implemented...\n"); //hci_send_raw_data(data, 16);#endif return 0;}intbt_send_dfu_command(int bt_cfd, int len, unsigned char *data){ static unsigned char buf[2048]; if (len > sizeof buf - sizeof(int)) { errno = EINVAL; return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -