1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2000-2002 Maxim Krasnyansky <maxk (at) qualcomm.com> 6 * Copyright (C) 2003-2011 Marcel Holtmann <marcel (at) holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #ifdef HAVE_CONFIG_H 26 #include <config.h> 27 #endif 28 29 #include <stdio.h> 30 #include <errno.h> 31 #include <ctype.h> 32 #include <unistd.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include <sys/types.h> 37 #include <netinet/in.h> 38 39 #include "parser.h" 40 #include "rfcomm.h" 41 42 struct parser_t parser; 43 44 void init_parser(unsigned long flags, unsigned long filter, 45 unsigned short defpsm, unsigned short defcompid, 46 int pppdump_fd, int audio_fd) 47 { 48 if ((flags & DUMP_RAW) && !(flags & DUMP_TYPE_MASK)) 49 flags |= DUMP_HEX; 50 51 parser.flags = flags; 52 parser.filter = filter; 53 parser.defpsm = defpsm; 54 parser.defcompid = defcompid; 55 parser.state = 0; 56 parser.pppdump_fd = pppdump_fd; 57 parser.audio_fd = audio_fd; 58 } 59 60 #define PROTO_TABLE_SIZE 20 61 62 static struct { 63 uint16_t handle; 64 uint16_t psm; 65 uint8_t channel; 66 uint32_t proto; 67 } proto_table[PROTO_TABLE_SIZE]; 68 69 void set_proto(uint16_t handle, uint16_t psm, uint8_t channel, uint32_t proto) 70 { 71 int i, pos = -1; 72 73 if (psm > 0 && psm < 0x1000 && !channel) 74 return; 75 76 if (!psm && channel) 77 psm = RFCOMM_PSM; 78 79 for (i = 0; i < PROTO_TABLE_SIZE; i++) { 80 if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel) { 81 pos = i; 82 break; 83 } 84 85 if (pos < 0 && !proto_table[i].handle && !proto_table[i].psm && !proto_table[i].channel) 86 pos = i; 87 } 88 89 if (pos < 0) 90 return; 91 92 proto_table[pos].handle = handle; 93 proto_table[pos].psm = psm; 94 proto_table[pos].channel = channel; 95 proto_table[pos].proto = proto; 96 } 97 98 uint32_t get_proto(uint16_t handle, uint16_t psm, uint8_t channel) 99 { 100 int i, pos = -1; 101 102 if (!psm && channel) 103 psm = RFCOMM_PSM; 104 105 for (i = 0; i < PROTO_TABLE_SIZE; i++) { 106 if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel) 107 return proto_table[i].proto; 108 109 if (!proto_table[i].handle) { 110 if (proto_table[i].psm == psm && proto_table[i].channel == channel) 111 pos = i; 112 } 113 } 114 115 return (pos < 0) ? 0 : proto_table[pos].proto; 116 } 117 118 #define FRAME_TABLE_SIZE 20 119 120 static struct { 121 uint16_t handle; 122 uint8_t dlci; 123 uint8_t opcode; 124 uint8_t status; 125 struct frame frm; 126 } frame_table[FRAME_TABLE_SIZE]; 127 128 void del_frame(uint16_t handle, uint8_t dlci) 129 { 130 int i; 131 132 for (i = 0; i < FRAME_TABLE_SIZE; i++) 133 if (frame_table[i].handle == handle && 134 frame_table[i].dlci == dlci) { 135 frame_table[i].handle = 0; 136 frame_table[i].dlci = 0; 137 frame_table[i].opcode = 0; 138 frame_table[i].status = 0; 139 if (frame_table[i].frm.data) 140 free(frame_table[i].frm.data); 141 memset(&frame_table[i].frm, 0, sizeof(struct frame)); 142 break; 143 } 144 } 145 146 struct frame *add_frame(struct frame *frm) 147 { 148 struct frame *fr; 149 void *data; 150 int i, pos = -1; 151 152 for (i = 0; i < FRAME_TABLE_SIZE; i++) { 153 if (frame_table[i].handle == frm->handle && 154 frame_table[i].dlci == frm->dlci) { 155 pos = i; 156 break; 157 } 158 159 if (pos < 0 && !frame_table[i].handle && !frame_table[i].dlci) 160 pos = i; 161 } 162 163 if (pos < 0) 164 return frm; 165 166 frame_table[pos].handle = frm->handle; 167 frame_table[pos].dlci = frm->dlci; 168 fr = &frame_table[pos].frm; 169 170 data = malloc(fr->len + frm->len); 171 if (!data) { 172 perror("Can't allocate frame stream buffer"); 173 del_frame(frm->handle, frm->dlci); 174 return frm; 175 } 176 177 if (fr->len > 0) 178 memcpy(data, fr->ptr, fr->len); 179 180 if (frm->len > 0) 181 memcpy(data + fr->len, frm->ptr, frm->len); 182 183 if (fr->data) 184 free(fr->data); 185 186 fr->data = data; 187 fr->data_len = fr->len + frm->len; 188 fr->len = fr->data_len; 189 fr->ptr = fr->data; 190 fr->dev_id = frm->dev_id; 191 fr->in = frm->in; 192 fr->ts = frm->ts; 193 fr->handle = frm->handle; 194 fr->cid = frm->cid; 195 fr->num = frm->num; 196 fr->dlci = frm->dlci; 197 fr->channel = frm->channel; 198 fr->pppdump_fd = frm->pppdump_fd; 199 fr->audio_fd = frm->audio_fd; 200 201 return fr; 202 } 203 204 uint8_t get_opcode(uint16_t handle, uint8_t dlci) 205 { 206 int i; 207 208 for (i = 0; i < FRAME_TABLE_SIZE; i++) 209 if (frame_table[i].handle == handle && 210 frame_table[i].dlci == dlci) 211 return frame_table[i].opcode; 212 213 return 0x00; 214 } 215 216 void set_opcode(uint16_t handle, uint8_t dlci, uint8_t opcode) 217 { 218 int i; 219 220 for (i = 0; i < FRAME_TABLE_SIZE; i++) 221 if (frame_table[i].handle == handle && 222 frame_table[i].dlci == dlci) { 223 frame_table[i].opcode = opcode; 224 break; 225 } 226 } 227 228 uint8_t get_status(uint16_t handle, uint8_t dlci) 229 { 230 int i; 231 232 for (i = 0; i < FRAME_TABLE_SIZE; i++) 233 if (frame_table[i].handle == handle && 234 frame_table[i].dlci == dlci) 235 return frame_table[i].status; 236 237 return 0x00; 238 } 239 240 void set_status(uint16_t handle, uint8_t dlci, uint8_t status) 241 { 242 int i; 243 244 for (i = 0; i < FRAME_TABLE_SIZE; i++) 245 if (frame_table[i].handle == handle && 246 frame_table[i].dlci == dlci) { 247 frame_table[i].status = status; 248 break; 249 } 250 } 251 252 void ascii_dump(int level, struct frame *frm, int num) 253 { 254 unsigned char *buf = frm->ptr; 255 register int i, n; 256 257 if ((num < 0) || (num > (int) frm->len)) 258 num = frm->len; 259 260 for (i = 0, n = 1; i < num; i++, n++) { 261 if (n == 1) 262 p_indent(level, frm); 263 printf("%1c ", isprint(buf[i]) ? buf[i] : '.'); 264 if (n == DUMP_WIDTH) { 265 printf("\n"); 266 n = 0; 267 } 268 } 269 if (i && n != 1) 270 printf("\n"); 271 } 272 273 void hex_dump(int level, struct frame *frm, int num) 274 { 275 unsigned char *buf = frm->ptr; 276 register int i, n; 277 278 if ((num < 0) || (num > (int) frm->len)) 279 num = frm->len; 280 281 for (i = 0, n = 1; i < num; i++, n++) { 282 if (n == 1) 283 p_indent(level, frm); 284 printf("%2.2X ", buf[i]); 285 if (n == DUMP_WIDTH) { 286 printf("\n"); 287 n = 0; 288 } 289 } 290 if (i && n != 1) 291 printf("\n"); 292 } 293 294 void ext_dump(int level, struct frame *frm, int num) 295 { 296 unsigned char *buf = frm->ptr; 297 register int i, n = 0, size; 298 299 if ((num < 0) || (num > (int) frm->len)) 300 num = frm->len; 301 302 while (num > 0) { 303 p_indent(level, frm); 304 printf("%04x: ", n); 305 306 size = num > 16 ? 16 : num; 307 308 for (i = 0; i < size; i++) 309 printf("%02x%s", buf[i], (i + 1) % 8 ? " " : " "); 310 for (i = size; i < 16; i++) 311 printf(" %s", (i + 1) % 8 ? " " : " "); 312 313 for (i = 0; i < size; i++) 314 printf("%1c", isprint(buf[i]) ? buf[i] : '.'); 315 printf("\n"); 316 317 buf += size; 318 num -= size; 319 n += size; 320 } 321 } 322 323 void raw_ndump(int level, struct frame *frm, int num) 324 { 325 if (!frm->len) 326 return; 327 328 switch (parser.flags & DUMP_TYPE_MASK) { 329 case DUMP_ASCII: 330 ascii_dump(level, frm, num); 331 break; 332 333 case DUMP_HEX: 334 hex_dump(level, frm, num); 335 break; 336 337 case DUMP_EXT: 338 ext_dump(level, frm, num); 339 break; 340 } 341 } 342 343 void raw_dump(int level, struct frame *frm) 344 { 345 raw_ndump(level, frm, -1); 346 } 347