| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <errno.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include "parser.h"
- #include "rfcomm.h"
- struct parser_t parser;
- void init_parser(unsigned long flags, unsigned long filter,
- unsigned short defpsm, unsigned short defcompid,
- int pppdump_fd, int audio_fd)
- {
- if ((flags & DUMP_RAW) && !(flags & DUMP_TYPE_MASK))
- flags |= DUMP_HEX;
- parser.flags = flags;
- parser.filter = filter;
- parser.defpsm = defpsm;
- parser.defcompid = defcompid;
- parser.state = 0;
- parser.pppdump_fd = pppdump_fd;
- parser.audio_fd = audio_fd;
- }
- #define PROTO_TABLE_SIZE 20
- static struct {
- uint16_t handle;
- uint16_t psm;
- uint8_t channel;
- uint32_t proto;
- } proto_table[PROTO_TABLE_SIZE];
- void set_proto(uint16_t handle, uint16_t psm, uint8_t channel, uint32_t proto)
- {
- int i, pos = -1;
- if (psm > 0 && psm < 0x1000 && !channel)
- return;
- if (!psm && channel)
- psm = RFCOMM_PSM;
- for (i = 0; i < PROTO_TABLE_SIZE; i++) {
- if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel) {
- pos = i;
- break;
- }
- if (pos < 0 && !proto_table[i].handle && !proto_table[i].psm && !proto_table[i].channel)
- pos = i;
- }
- if (pos < 0)
- return;
- proto_table[pos].handle = handle;
- proto_table[pos].psm = psm;
- proto_table[pos].channel = channel;
- proto_table[pos].proto = proto;
- }
- uint32_t get_proto(uint16_t handle, uint16_t psm, uint8_t channel)
- {
- int i, pos = -1;
- if (!psm && channel)
- psm = RFCOMM_PSM;
- for (i = 0; i < PROTO_TABLE_SIZE; i++) {
- if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel)
- return proto_table[i].proto;
- if (!proto_table[i].handle) {
- if (proto_table[i].psm == psm && proto_table[i].channel == channel)
- pos = i;
- }
- }
- return (pos < 0) ? 0 : proto_table[pos].proto;
- }
- #define FRAME_TABLE_SIZE 20
- static struct {
- uint16_t handle;
- uint8_t dlci;
- uint8_t opcode;
- uint8_t status;
- struct frame frm;
- } frame_table[FRAME_TABLE_SIZE];
- void del_frame(uint16_t handle, uint8_t dlci)
- {
- int i;
- for (i = 0; i < FRAME_TABLE_SIZE; i++)
- if (frame_table[i].handle == handle &&
- frame_table[i].dlci == dlci) {
- frame_table[i].handle = 0;
- frame_table[i].dlci = 0;
- frame_table[i].opcode = 0;
- frame_table[i].status = 0;
- if (frame_table[i].frm.data)
- free(frame_table[i].frm.data);
- memset(&frame_table[i].frm, 0, sizeof(struct frame));
- break;
- }
- }
- struct frame *add_frame(struct frame *frm)
- {
- struct frame *fr;
- void *data;
- int i, pos = -1;
- for (i = 0; i < FRAME_TABLE_SIZE; i++) {
- if (frame_table[i].handle == frm->handle &&
- frame_table[i].dlci == frm->dlci) {
- pos = i;
- break;
- }
- if (pos < 0 && !frame_table[i].handle && !frame_table[i].dlci)
- pos = i;
- }
- if (pos < 0)
- return frm;
- frame_table[pos].handle = frm->handle;
- frame_table[pos].dlci = frm->dlci;
- fr = &frame_table[pos].frm;
- data = malloc(fr->len + frm->len);
- if (!data) {
- perror("Can't allocate frame stream buffer");
- del_frame(frm->handle, frm->dlci);
- return frm;
- }
- if (fr->len > 0)
- memcpy(data, fr->ptr, fr->len);
- if (frm->len > 0)
- memcpy(data + fr->len, frm->ptr, frm->len);
- if (fr->data)
- free(fr->data);
- fr->data = data;
- fr->data_len = fr->len + frm->len;
- fr->len = fr->data_len;
- fr->ptr = fr->data;
- fr->dev_id = frm->dev_id;
- fr->in = frm->in;
- fr->ts = frm->ts;
- fr->handle = frm->handle;
- fr->cid = frm->cid;
- fr->num = frm->num;
- fr->dlci = frm->dlci;
- fr->channel = frm->channel;
- fr->pppdump_fd = frm->pppdump_fd;
- fr->audio_fd = frm->audio_fd;
- return fr;
- }
- uint8_t get_opcode(uint16_t handle, uint8_t dlci)
- {
- int i;
- for (i = 0; i < FRAME_TABLE_SIZE; i++)
- if (frame_table[i].handle == handle &&
- frame_table[i].dlci == dlci)
- return frame_table[i].opcode;
- return 0x00;
- }
- void set_opcode(uint16_t handle, uint8_t dlci, uint8_t opcode)
- {
- int i;
- for (i = 0; i < FRAME_TABLE_SIZE; i++)
- if (frame_table[i].handle == handle &&
- frame_table[i].dlci == dlci) {
- frame_table[i].opcode = opcode;
- break;
- }
- }
- uint8_t get_status(uint16_t handle, uint8_t dlci)
- {
- int i;
- for (i = 0; i < FRAME_TABLE_SIZE; i++)
- if (frame_table[i].handle == handle &&
- frame_table[i].dlci == dlci)
- return frame_table[i].status;
- return 0x00;
- }
- void set_status(uint16_t handle, uint8_t dlci, uint8_t status)
- {
- int i;
- for (i = 0; i < FRAME_TABLE_SIZE; i++)
- if (frame_table[i].handle == handle &&
- frame_table[i].dlci == dlci) {
- frame_table[i].status = status;
- break;
- }
- }
- void ascii_dump(int level, struct frame *frm, int num)
- {
- unsigned char *buf = frm->ptr;
- register int i, n;
- if ((num < 0) || (num > (int) frm->len))
- num = frm->len;
- for (i = 0, n = 1; i < num; i++, n++) {
- if (n == 1)
- p_indent(level, frm);
- printf("%1c ", isprint(buf[i]) ? buf[i] : '.');
- if (n == DUMP_WIDTH) {
- printf("\n");
- n = 0;
- }
- }
- if (i && n != 1)
- printf("\n");
- }
- void hex_dump(int level, struct frame *frm, int num)
- {
- unsigned char *buf = frm->ptr;
- register int i, n;
- if ((num < 0) || (num > (int) frm->len))
- num = frm->len;
- for (i = 0, n = 1; i < num; i++, n++) {
- if (n == 1)
- p_indent(level, frm);
- printf("%2.2X ", buf[i]);
- if (n == DUMP_WIDTH) {
- printf("\n");
- n = 0;
- }
- }
- if (i && n != 1)
- printf("\n");
- }
- void ext_dump(int level, struct frame *frm, int num)
- {
- unsigned char *buf = frm->ptr;
- register int i, n = 0, size;
- if ((num < 0) || (num > (int) frm->len))
- num = frm->len;
- while (num > 0) {
- p_indent(level, frm);
- printf("%04x: ", n);
- size = num > 16 ? 16 : num;
- for (i = 0; i < size; i++)
- printf("%02x%s", buf[i], (i + 1) % 8 ? " " : " ");
- for (i = size; i < 16; i++)
- printf(" %s", (i + 1) % 8 ? " " : " ");
- for (i = 0; i < size; i++)
- printf("%1c", isprint(buf[i]) ? buf[i] : '.');
- printf("\n");
- buf += size;
- num -= size;
- n += size;
- }
- }
- void raw_ndump(int level, struct frame *frm, int num)
- {
- if (!frm->len)
- return;
- switch (parser.flags & DUMP_TYPE_MASK) {
- case DUMP_ASCII:
- ascii_dump(level, frm, num);
- break;
- case DUMP_HEX:
- hex_dump(level, frm, num);
- break;
- case DUMP_EXT:
- ext_dump(level, frm, num);
- break;
- }
- }
- void raw_dump(int level, struct frame *frm)
- {
- raw_ndump(level, frm, -1);
- }
|