📄 btctl-dev.c
字号:
memset(resp,'\0', 100); /* Switch to default Texas baudrate*/ if (set_speed(fd, ti, 115200) < 0) { perror("Can't set default baud rate"); return -1; } /* It is possible to get software version with manufacturer specific HCI command HCI_VS_TI_Version_Number. But the only thing you get more is if this is point-to-point or point-to-multipoint module */ /* Get Manufacturer and LMP version */ cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x01; cmd[2] = 0x10; cmd[3] = 0x00; do { n = write(fd, cmd, 4); if (n < 0) { perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); return -1; } if (n < 4) { fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); return -1; } /* Read reply. */ if (read_hci_event(fd, resp, 100) < 0) { perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); return -1; } /* Wait for command complete event for our Opcode */ } while (resp[4] != cmd[1] && resp[5] != cmd[2]); /* Verify manufacturer */ if ((resp[11] & 0xFF) != 0x0d) fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); /* Print LMP version */ fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); /* Print LMP subversion */ fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); nanosleep(&tm, NULL); return 0;}#endifstruct uart_t uart[] = { /* can be any card */ { "h4", 1, HCI_UART_H4, 115200, 115200, CRTSCTS, NULL }, /* nokia */ { "tlp", 2, HCI_UART_TLP, 115200, 115200, AFFIX_UART_RI | AFFIX_UART_LOW | CRTSCTS, NULL }, /* csr bcsp */ { "bcsp", 3, HCI_UART_BCSP, 115200, 115200, PARENB, NULL }, /* CSR */ { "csr", 4, HCI_UART_H4, 115200, 115200, CRTSCTS, csr }, /* ericsson */ { "ericsson", 5, HCI_UART_H4, 115200, 57600, CRTSCTS, ericsson }, /* digi */ { "digi", 6, HCI_UART_H4, 115200, 9600, CRTSCTS, digi }, /* Silicon Wave */ { "swave", 7, HCI_UART_H4, 115200, 115200, CRTSCTS, swave }, { NULL, 0 }};struct uart_t * get_by_type(char *name){ int i, speed = 0; int m_id, p_id, mid, pid; char linebuf[80]; char iftype[32], type[32], flags[32] = {'\0'}; char *ch; FILE *fp; struct uart_t *u = NULL; i = sscanf(name, "%x:%x", &m_id, &p_id); if (i > 1) { /* we have 0x:0x type here * read info from config_file */ fp = fopen(uart_map, "r"); if (!fp) { BTERROR("unable to open map file\n"); return NULL; } type[0] = '\0'; for (; fgets(linebuf, sizeof(linebuf), fp);) { ch = strchr(linebuf, '#'); if (ch) *ch = '\0'; type[0] = '\0'; speed = 0; flags[0] = '\0'; i = sscanf(linebuf, "%s %x:%x %s %d %s", iftype, &mid, &pid, type, &speed, flags); if (i < 3) continue; //printf("%s %x:%x %s %d %s\n", iftype, mid, pid, type, speed, flags); if (strcasecmp(iftype, "uart") != 0) continue; if (m_id == mid && p_id == pid) { /* found it" */ name = type; break; } } fclose(fp); if (type[0] == '\0') { /* try H4 */ name = "h4"; } } for (i = 0; uart[i].name; i++) { if (!strcmp(uart[i].name, name)) { u = &uart[i]; break; } } if (!u) return NULL; if (speed) u->speed = speed; if (flags[0] != '\0') { u->flags = 0; if (!str2mask(uart_flags, flags, &u->flags)) { BTERROR("flags error\n"); return NULL; } } //printf("type: %s, speed: %d, flags: %x\n", u->name, u->speed, u->flags); return u;}static void sig_alarm(int sig){ BTERROR("Initialization timed out.\n"); if (hci >= 0) { hci_stop_dev(hci); close(hci); } exit(1);}/* Initialize UART device */int init_uart(char *dev, struct uart_t *u){ struct termios ti; int fd, err; int to = 20, speed; /* now device ready for initialization */ signal(SIGALRM, &sig_alarm); alarm(to); BTINFO("Initializing UART"); if (uart_rate) speed = uart_speed(uart_rate > 0 ? uart_rate : u->init_speed); else speed = 0; err = hci_setup_uart(dev, u->proto, speed, u->flags); if (err) return err; /* Vendor specific initialization */ if (u->init) { fd = _hci_open(dev); if (fd < 0) { BTERROR("unable to open: %s\n", dev); return fd; } err = u->init(fd, u, &ti); close(fd); } /* Set actual baudrate */ if (!err) { err = hci_setup_uart(dev, u->proto, uart_speed(u->speed), u->flags); if (err) BTERROR("Can't setup uart"); } alarm(0); return err;}int cmd_uart(struct btctl_command *cmd){ int err; char *dev = NULL; struct uart_t *u = NULL; closelog(); openlog(argv[0], LOG_PERROR|LOG_PID, LOG_USER); if (argc - argind < 1 || (cmd->cmd == CMD_OPEN_UART && argc - argind < 2)) { print_usage(cmd); exit(1); } if (cmd->cmd != CMD_INIT_UART) dev = argv[argind++]; if (cmd->cmd != CMD_CLOSE_UART) { u = get_by_type(argv[argind++]); if (!u) { BTERROR("Device unknown.\n"); return 1; } if (!argv[argind]) goto next; u->speed = atoi(argv[argind++]); if (!argv[argind]) goto next; /* get 0xXXXX flags */ if (sscanf(argv[argind], "0x%x", &u->flags) > 0) goto next; else { char buf[80]; /* get symbolic */ argv2str(buf, &argv[argind]); u->flags = 0; if (!str2mask(uart_flags, buf, &u->flags)) { BTERROR("flags error\n"); return -1; } }next: if (cmd->cmd == CMD_OPEN_UART) { /* atatch device */ err = hci_open_uart(dev, u->type, u->proto, uart_speed(u->speed), u->flags); } else { /* init device */ err = init_uart(btdev, u); if (err < 0) BTERROR("Can't init device\n"); } } else { err = hci_close_uart(dev); } if (err) BTERROR("%s", hci_error(err)); return err;}int cmd_initdev(struct btctl_command *cmd){ int err; if (cmd->cmd == CMD_INITDEV && !argv[argind]) { BTERROR("device type missed\n"); return -1; } /* open HCI device */ hci = _hci_open(btdev); if (hci < 0) { BTERROR("unable to open: %s, %s (%d)\n", btdev, strerror(errno), errno); return -1; } if (cmd->cmd == CMD_UPDEV) err = hci_start_dev(hci); else err = hci_stop_dev(hci); if (err) { BTERROR("Unable to %s device (%s)\n", cmd->cmd == CMD_UPDEV ? "start" : "stop", btdev); return err; } /* do stuff */ if (cmd->cmd == CMD_INITDEV) { if (strcasecmp(argv[argind], "usb") == 0) { } else if (strcasecmp(argv[argind], "pcmcia") == 0) { } else if (strcasecmp(argv[argind], "uart") == 0) { } else if (strcasecmp(argv[argind], "uart_cs") == 0) { } } /* close HCI device */ if (cmd->cmd == CMD_INITDEV) hci_stop_dev(hci); close(hci); hci = -1; return 0;}/* --------------------- HCI packet dumper --------------------- */#define PCAP_MAGIC 0xa1b2c3d4#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1#define PCAP_MODIFIED_MAGIC 0xa1b2cd34#define PCAP_SWAPPED_MODIFIED_MAGIC 0x34cdb2a1/* "libpcap" file header (minus magic number). */struct pcap_file_hdr { uint32_t magic; /* magic */ uint16_t version_major; /* major version number */ uint16_t version_minor; /* minor version number */ int32_t thiszone; /* GMT to local correction */ uint32_t sigfigs; /* accuracy of timestamps */ uint32_t snaplen; /* max length of captured packets, in octets -> max length saved portion of each pkt */ uint32_t linktype; /* data link type */ uint8_t data[0];} __PACK__;/* "libpcap" record header. */struct pcap_pkt_hdr { struct timeval ts; /* time stamp */ uint32_t caplen; /* number of octets of packet saved in file */ uint32_t len; /* actual length of packet */ uint8_t data[0];} __PACK__;struct pcap_eth_hdr { uint8_t dst[6]; uint8_t src[6]; uint16_t proto; uint8_t data[0];} __PACK__;int cmd_capture(struct btctl_command *cmd){ int rfd, wfd, promisc = 1; struct sockaddr_affix sa; socklen_t salen = sizeof(sa); char packet[65535]; // for now int size, pkt_type; struct pcap_file_hdr hdr; struct pcap_pkt_hdr *pcap = (void*)packet; struct pcap_eth_hdr *eth = (void*)pcap->data; struct hci_dev_attr attr; unsigned long rx_acl = 0, rx_sco = 0, rx_event = 0; unsigned long tx_acl = 0, tx_sco = 0, tx_cmd = 0; if (!argv[argind]) { fprintf(stderr, "usage: hcidump <filename> | -\n"); return 1; } if (argv[argind][0] == '-') wfd = 1; else { wfd = open(argv[argind], O_WRONLY|O_CREAT|O_TRUNC, 0644); if (wfd < 0) { fprintf(stderr, "%s open failed: %s\n", argv[argind], strerror(errno)); return 1; } } rfd = hci_open(btdev); if (rfd < 0) { fprintf(stderr, "hci_open() faield\n"); return 1; } if (setsockopt(rfd, SOL_AFFIX, BTSO_PROMISC, &promisc, sizeof(int))) { fprintf(stderr, "setsockopt() failed\n"); return 1; } /* init file header */ memset(&hdr, 0, sizeof(hdr)); hdr.magic = PCAP_MAGIC; hdr.version_major = 2; hdr.version_minor = 4; hdr.snaplen = 0xffff; //FIXME hdr.linktype = 1; //Ethernet size = write(wfd, &hdr, sizeof(hdr)); if (size < 0) { fprintf(stderr, "write failed: %s\n", strerror(errno)); return 1; } /* init SLL header */ eth->proto = htons(0xb123); //fprintf(stderr, "Capturing...\n"); for (;;) { fprintf(stderr, "Captured: RX: acl:%lu sco:%lu event:%lu", rx_acl, rx_sco, rx_event); fprintf(stderr, ", TX: acl:%lu sco:%lu cmd:%lu\r", tx_acl, tx_sco, tx_cmd); fflush(stderr); /* reading HCI packet ... */ size = recvfrom(rfd, eth->data, sizeof(packet), 0, (struct sockaddr*)&sa, &salen); if (size < 0) { fprintf(stderr, "recvfrom failed: %s\n", strerror(errno)); return 1; } hci_get_attr_id(sa.devnum, &attr); //fprintf(stderr, "recvfrom(): %d bytes, bda: %s\n", size, bda2str(&sa.bda)); /* init SLL header */ pkt_type = eth->data[0] & ~HCI_PKT_OUTGOING; if (eth->data[0] & HCI_PKT_OUTGOING) { bda2eth(eth->src, &attr.bda); if (pkt_type == HCI_COMMAND) { bda2eth(eth->dst, &attr.bda); tx_cmd++; } else { bda2eth(eth->dst, &sa.bda); if (pkt_type == HCI_ACL) tx_acl++; else tx_sco++; } } else { bda2eth(eth->dst, &attr.bda); if (pkt_type == HCI_EVENT) { bda2eth(eth->src, &attr.bda); rx_event++; } else { bda2eth(eth->src, &sa.bda); if (pkt_type == HCI_ACL) rx_acl++; else rx_sco++; } } size += sizeof(*eth); /* init pcap header */ gettimeofday(&pcap->ts, NULL); pcap->caplen = size; pcap->len = size; size += sizeof(*pcap); //fprintf(stderr, "write: %d, sizeof(*pcap): %d, sizeof(*sll): %d\n", // size, sizeof(*pcap), sizeof(*sll)); size = write(wfd, packet, size); if (size < 0) { fprintf(stderr, "write failed: %s\n", strerror(errno)); return 1; } } fprintf(stderr, "\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -