• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2004-2011  Marcel Holtmann <marcel@holtmann.org>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include <sys/types.h>
35 #include <netinet/in.h>
36 
37 #include "parser.h"
38 
39 #define CSR_U8(frm)  (get_u8(frm))
40 #define CSR_U16(frm) (btohs(htons(get_u16(frm))))
41 #define CSR_U32(frm) ((CSR_U16(frm) << 16) + CSR_U16(frm))
42 #define CSR_S16(frm) (btohs(htons(get_u16(frm))))
43 
type2str(uint16_t type)44 static char *type2str(uint16_t type)
45 {
46 	switch (type) {
47 	case 0x0000:
48 		return "Get req";
49 	case 0x0001:
50 		return "Get rsp";
51 	case 0x0002:
52 		return "Set req";
53 	default:
54 		return "Reserved";
55 	}
56 }
57 
valueless_dump(int level,char * str,struct frame * frm)58 static inline void valueless_dump(int level, char *str, struct frame *frm)
59 {
60 	p_indent(level, frm);
61 	printf("%s\n", str);
62 }
63 
complex_dump(int level,char * str,struct frame * frm)64 static inline void complex_dump(int level, char *str, struct frame *frm)
65 {
66 	p_indent(level, frm);
67 	printf("%s\n", str);
68 
69 	raw_dump(level, frm);
70 }
71 
bool_dump(int level,char * str,struct frame * frm)72 static inline void bool_dump(int level, char *str, struct frame *frm)
73 {
74 	uint16_t value;
75 
76 	value = CSR_U16(frm);
77 
78 	p_indent(level, frm);
79 	printf("%s: value %s (%d)\n", str, value ? "TRUE" : "FALSE", value);
80 }
81 
int8_dump(int level,char * str,struct frame * frm)82 static inline void int8_dump(int level, char *str, struct frame *frm)
83 {
84 	int16_t value;
85 
86 	value = CSR_S16(frm);
87 
88 	p_indent(level, frm);
89 	printf("%s: value %d (0x%2.2x)\n", str, value, value);
90 }
91 
int16_dump(int level,char * str,struct frame * frm)92 static inline void int16_dump(int level, char *str, struct frame *frm)
93 {
94 	int16_t value;
95 
96 	value = CSR_S16(frm);
97 
98 	p_indent(level, frm);
99 	printf("%s: value %d (0x%2.2x)\n", str, value, value);
100 }
101 
uint16_dump(int level,char * str,struct frame * frm)102 static inline void uint16_dump(int level, char *str, struct frame *frm)
103 {
104 	uint16_t value;
105 
106 	value = CSR_U16(frm);
107 
108 	p_indent(level, frm);
109 	printf("%s: value %d (0x%4.4x)\n", str, value, value);
110 }
111 
uint32_dump(int level,char * str,struct frame * frm)112 static inline void uint32_dump(int level, char *str, struct frame *frm)
113 {
114 	uint32_t value;
115 
116 	value = CSR_U32(frm);
117 
118 	p_indent(level, frm);
119 	printf("%s: value %d (0x%4.4x)\n", str, value, value);
120 }
121 
bdaddr_dump(int level,char * str,struct frame * frm)122 static inline void bdaddr_dump(int level, char *str, struct frame *frm)
123 {
124 	char addr[18];
125 
126 	p_ba2str(frm->ptr, addr);
127 
128 	p_indent(level, frm);
129 	printf("%s: bdaddr %s\n", str, addr);
130 }
131 
features_dump(int level,char * str,struct frame * frm)132 static inline void features_dump(int level, char *str, struct frame *frm)
133 {
134 	unsigned char features[8];
135 	int i;
136 
137 	memcpy(features, frm->ptr, 8);
138 
139 	p_indent(level, frm);
140 	printf("%s: features", str);
141 	for (i = 0; i < 8; i++)
142 		printf(" 0x%02x", features[i]);
143 	printf("\n");
144 }
145 
commands_dump(int level,char * str,struct frame * frm)146 static inline void commands_dump(int level, char *str, struct frame *frm)
147 {
148 	unsigned char commands[64];
149 	unsigned int i;
150 
151 	memcpy(commands, frm->ptr, frm->len);
152 
153 	p_indent(level, frm);
154 	printf("%s: commands", str);
155 	for (i = 0; i < frm->len; i++)
156 		printf(" 0x%02x", commands[i]);
157 	printf("\n");
158 }
159 
handle_length_dump(int level,char * str,struct frame * frm)160 static inline void handle_length_dump(int level, char *str, struct frame *frm)
161 {
162 	uint16_t handle, length;
163 
164 	handle = CSR_U16(frm);
165 	length = CSR_U16(frm);
166 
167 	p_indent(level, frm);
168 	printf("%s: handle %d length %d\n", str, handle, length);
169 }
170 
handle_clock_dump(int level,char * str,struct frame * frm)171 static inline void handle_clock_dump(int level, char *str, struct frame *frm)
172 {
173 	uint16_t handle;
174 	uint32_t clock;
175 
176 	handle = CSR_U16(frm);
177 	clock  = CSR_U32(frm);
178 
179 	p_indent(level, frm);
180 	printf("%s: handle %d clock 0x%4.4x\n", str, handle, clock);
181 }
182 
radiotest_dump(int level,char * str,struct frame * frm)183 static inline void radiotest_dump(int level, char *str, struct frame *frm)
184 {
185 	uint16_t testid;
186 
187 	testid = CSR_U16(frm);
188 
189 	p_indent(level, frm);
190 	printf("%s: test id %d\n", str, testid);
191 
192 	raw_dump(level, frm);
193 }
194 
psmemtype_dump(int level,char * str,struct frame * frm)195 static inline void psmemtype_dump(int level, char *str, struct frame *frm)
196 {
197 	uint16_t store, type;
198 
199 	store = CSR_U16(frm);
200 	type  = CSR_U16(frm);
201 
202 	p_indent(level, frm);
203 	printf("%s: store 0x%4.4x type %d\n", str, store, type);
204 }
205 
psnext_dump(int level,char * str,struct frame * frm)206 static inline void psnext_dump(int level, char *str, struct frame *frm)
207 {
208 	uint16_t key, stores, next;
209 
210 	key    = CSR_U16(frm);
211 	stores = CSR_U16(frm);
212 	next   = CSR_U16(frm);
213 
214 	p_indent(level, frm);
215 	printf("%s: key 0x%4.4x stores 0x%4.4x next 0x%4.4x\n", str, key, stores, next);
216 }
217 
pssize_dump(int level,char * str,struct frame * frm)218 static inline void pssize_dump(int level, char *str, struct frame *frm)
219 {
220 	uint16_t key, length;
221 
222 	key    = CSR_U16(frm);
223 	length = CSR_U16(frm);
224 
225 	p_indent(level, frm);
226 	printf("%s: key 0x%4.4x %s 0x%4.4x\n", str, key,
227 				frm->in ? "len" : "stores", length);
228 }
229 
psstores_dump(int level,char * str,struct frame * frm)230 static inline void psstores_dump(int level, char *str, struct frame *frm)
231 {
232 	uint16_t key, stores;
233 
234 	key    = CSR_U16(frm);
235 	stores = CSR_U16(frm);
236 
237 	p_indent(level, frm);
238 	printf("%s: key 0x%4.4x stores 0x%4.4x\n", str, key, stores);
239 }
240 
pskey_dump(int level,struct frame * frm)241 static inline void pskey_dump(int level, struct frame *frm)
242 {
243 	uint16_t key, length, stores;
244 
245 	key    = CSR_U16(frm);
246 	length = CSR_U16(frm);
247 	stores = CSR_U16(frm);
248 
249 	p_indent(level, frm);
250 	printf("PSKEY: key 0x%4.4x len %d stores 0x%4.4x\n", key, length, stores);
251 
252 	switch (key) {
253 	case 0x0001:
254 		bdaddr_dump(level + 1, "BDADDR", frm);
255 		break;
256 	case 0x0002:
257 		uint16_dump(level + 1, "COUNTRYCODE", frm);
258 		break;
259 	case 0x0003:
260 		uint32_dump(level + 1, "CLASSOFDEVICE", frm);
261 		break;
262 	case 0x0004:
263 		uint16_dump(level + 1, "DEVICE_DRIFT", frm);
264 		break;
265 	case 0x0005:
266 		uint16_dump(level + 1, "DEVICE_JITTER", frm);
267 		break;
268 	case 0x000d:
269 		uint16_dump(level + 1, "MAX_ACLS", frm);
270 		break;
271 	case 0x000e:
272 		uint16_dump(level + 1, "MAX_SCOS", frm);
273 		break;
274 	case 0x000f:
275 		uint16_dump(level + 1, "MAX_REMOTE_MASTERS", frm);
276 		break;
277 	case 0x00da:
278 		uint16_dump(level + 1, "ENC_KEY_LMIN", frm);
279 		break;
280 	case 0x00db:
281 		uint16_dump(level + 1, "ENC_KEY_LMAX", frm);
282 		break;
283 	case 0x00ef:
284 		features_dump(level + 1, "LOCAL_SUPPORTED_FEATURES", frm);
285 		break;
286 	case 0x0106:
287 		commands_dump(level + 1, "LOCAL_SUPPORTED_COMMANDS", frm);
288 		break;
289 	case 0x010d:
290 		uint16_dump(level + 1, "HCI_LMP_LOCAL_VERSION", frm);
291 		break;
292 	case 0x010e:
293 		uint16_dump(level + 1, "LMP_REMOTE_VERSION", frm);
294 		break;
295 	case 0x01a5:
296 		bool_dump(level + 1, "HOSTIO_USE_HCI_EXTN", frm);
297 		break;
298 	case 0x01ab:
299 		bool_dump(level + 1, "HOSTIO_MAP_SCO_PCM", frm);
300 		break;
301 	case 0x01be:
302 		uint16_dump(level + 1, "UART_BAUDRATE", frm);
303 		break;
304 	case 0x01f6:
305 		uint16_dump(level + 1, "ANA_FTRIM", frm);
306 		break;
307 	case 0x01f9:
308 		uint16_dump(level + 1, "HOST_INTERFACE", frm);
309 		break;
310 	case 0x01fe:
311 		uint16_dump(level + 1, "ANA_FREQ", frm);
312 		break;
313 	case 0x02be:
314 		uint16_dump(level + 1, "USB_VENDOR_ID", frm);
315 		break;
316 	case 0x02bf:
317 		uint16_dump(level + 1, "USB_PRODUCT_ID", frm);
318 		break;
319 	case 0x02cb:
320 		uint16_dump(level + 1, "USB_DFU_PRODUCT_ID", frm);
321 		break;
322 	case 0x03cd:
323 		int16_dump(level + 1, "INITIAL_BOOTMODE", frm);
324 		break;
325 	default:
326 		raw_dump(level + 1, frm);
327 		break;
328 	}
329 }
330 
bccmd_dump(int level,struct frame * frm)331 static inline void bccmd_dump(int level, struct frame *frm)
332 {
333 	uint16_t type, length, seqno, varid, status;
334 
335 	type   = CSR_U16(frm);
336 	length = CSR_U16(frm);
337 	seqno  = CSR_U16(frm);
338 	varid  = CSR_U16(frm);
339 	status = CSR_U16(frm);
340 
341 	p_indent(level, frm);
342 	printf("BCCMD: %s: len %d seqno %d varid 0x%4.4x status %d\n",
343 			type2str(type), length, seqno, varid, status);
344 
345 	if (!(parser.flags & DUMP_VERBOSE)) {
346 		raw_dump(level + 1, frm);
347 		return;
348 	}
349 
350 	switch (varid) {
351 	case 0x000b:
352 		valueless_dump(level + 1, "PS_CLR_ALL", frm);
353 		break;
354 	case 0x000c:
355 		valueless_dump(level + 1, "PS_FACTORY_SET", frm);
356 		break;
357 	case 0x082d:
358 		uint16_dump(level + 1, "PS_CLR_ALL_STORES", frm);
359 		break;
360 	case 0x2801:
361 		uint16_dump(level + 1, "BC01_STATUS", frm);
362 		break;
363 	case 0x2819:
364 		uint16_dump(level + 1, "BUILDID", frm);
365 		break;
366 	case 0x281a:
367 		uint16_dump(level + 1, "CHIPVER", frm);
368 		break;
369 	case 0x281b:
370 		uint16_dump(level + 1, "CHIPREV", frm);
371 		break;
372 	case 0x2825:
373 		uint16_dump(level + 1, "INTERFACE_VERSION", frm);
374 		break;
375 	case 0x282a:
376 		uint16_dump(level + 1, "RAND", frm);
377 		break;
378 	case 0x282c:
379 		uint16_dump(level + 1, "MAX_CRYPT_KEY_LENGTH", frm);
380 		break;
381 	case 0x2833:
382 		uint16_dump(level + 1, "E2_APP_SIZE", frm);
383 		break;
384 	case 0x2836:
385 		uint16_dump(level + 1, "CHIPANAREV", frm);
386 		break;
387 	case 0x2838:
388 		uint16_dump(level + 1, "BUILDID_LOADER", frm);
389 		break;
390 	case 0x2c00:
391 		uint32_dump(level + 1, "BT_CLOCK", frm);
392 		break;
393 	case 0x3005:
394 		psnext_dump(level + 1, "PS_NEXT", frm);
395 		break;
396 	case 0x3006:
397 		pssize_dump(level + 1, "PS_SIZE", frm);
398 		break;
399 	case 0x3008:
400 		handle_length_dump(level + 1, "CRYPT_KEY_LENGTH", frm);
401 		break;
402 	case 0x3009:
403 		handle_clock_dump(level + 1, "PICONET_INSTANCE", frm);
404 		break;
405 	case 0x300a:
406 		complex_dump(level + 1, "GET_CLR_EVT", frm);
407 		break;
408 	case 0x300b:
409 		complex_dump(level + 1, "GET_NEXT_BUILDDEF", frm);
410 		break;
411 	case 0x300e:
412 		complex_dump(level + 1, "E2_DEVICE", frm);
413 		break;
414 	case 0x300f:
415 		complex_dump(level + 1, "E2_APP_DATA", frm);
416 		break;
417 	case 0x3012:
418 		psmemtype_dump(level + 1, "PS_MEMORY_TYPE", frm);
419 		break;
420 	case 0x301c:
421 		complex_dump(level + 1, "READ_BUILD_NAME", frm);
422 		break;
423 	case 0x4001:
424 		valueless_dump(level + 1, "COLD_RESET", frm);
425 		break;
426 	case 0x4002:
427 		valueless_dump(level + 1, "WARM_RESET", frm);
428 		break;
429 	case 0x4003:
430 		valueless_dump(level + 1, "COLD_HALT", frm);
431 		break;
432 	case 0x4004:
433 		valueless_dump(level + 1, "WARM_HALT", frm);
434 		break;
435 	case 0x4005:
436 		valueless_dump(level + 1, "INIT_BT_STACK", frm);
437 		break;
438 	case 0x4006:
439 		valueless_dump(level + 1, "ACTIVATE_BT_STACK", frm);
440 		break;
441 	case 0x4007:
442 		valueless_dump(level + 1, "ENABLE_TX", frm);
443 		break;
444 	case 0x4008:
445 		valueless_dump(level + 1, "DISABLE_TX", frm);
446 		break;
447 	case 0x4009:
448 		valueless_dump(level + 1, "RECAL", frm);
449 		break;
450 	case 0x400d:
451 		valueless_dump(level + 1, "PS_FACTORY_RESTORE", frm);
452 		break;
453 	case 0x400e:
454 		valueless_dump(level + 1, "PS_FACTORY_RESTORE_ALL", frm);
455 		break;
456 	case 0x400f:
457 		valueless_dump(level + 1, "PS_DEFRAG_RESET", frm);
458 		break;
459 	case 0x4011:
460 		valueless_dump(level + 1, "HOPPING_ON", frm);
461 		break;
462 	case 0x4012:
463 		valueless_dump(level + 1, "CANCEL_PAGE", frm);
464 		break;
465 	case 0x4818:
466 		uint16_dump(level + 1, "PS_CLR", frm);
467 		break;
468 	case 0x481c:
469 		uint16_dump(level + 1, "MAP_SCO_PCM", frm);
470 		break;
471 	case 0x482e:
472 		uint16_dump(level + 1, "SINGLE_CHAN", frm);
473 		break;
474 	case 0x5004:
475 		radiotest_dump(level + 1, "RADIOTEST", frm);
476 		break;
477 	case 0x500c:
478 		psstores_dump(level + 1, "PS_CLR_STORES", frm);
479 		break;
480 	case 0x6000:
481 		valueless_dump(level + 1, "NO_VARIABLE", frm);
482 		break;
483 	case 0x6802:
484 		uint16_dump(level + 1, "CONFIG_UART", frm);
485 		break;
486 	case 0x6805:
487 		uint16_dump(level + 1, "PANIC_ARG", frm);
488 		break;
489 	case 0x6806:
490 		uint16_dump(level + 1, "FAULT_ARG", frm);
491 		break;
492 	case 0x6827:
493 		int8_dump(level + 1, "MAX_TX_POWER", frm);
494 		break;
495 	case 0x682b:
496 		int8_dump(level + 1, "DEFAULT_TX_POWER", frm);
497 		break;
498 	case 0x7003:
499 		pskey_dump(level + 1, frm);
500 		break;
501 	default:
502 		raw_dump(level + 1, frm);
503 		break;
504 	}
505 }
506 
cid2str(uint8_t cid)507 static char *cid2str(uint8_t cid)
508 {
509 	switch (cid & 0x3f) {
510 	case 0:
511 		return "BCSP Internal";
512 	case 1:
513 		return "BCSP Link";
514 	case 2:
515 		return "BCCMD";
516 	case 3:
517 		return "HQ";
518 	case 4:
519 		return "Device Mgt";
520 	case 5:
521 		return "HCI Cmd/Evt";
522 	case 6:
523 		return "HCI ACL";
524 	case 7:
525 		return "HCI SCO";
526 	case 8:
527 		return "L2CAP";
528 	case 9:
529 		return "RFCOMM";
530 	case 10:
531 		return "SDP";
532 	case 11:
533 		return "Debug";
534 	case 12:
535 		return "DFU";
536 	case 13:
537 		return "VM";
538 	case 14:
539 		return "Unused";
540 	case 15:
541 		return "Reserved";
542 	default:
543 		return "Unknown";
544 	}
545 }
546 
frag2str(uint8_t frag)547 static char *frag2str(uint8_t frag)
548 {
549 	switch (frag & 0xc0) {
550 	case 0x00:
551 		return " middle fragment";
552 	case 0x40:
553 		return " first fragment";
554 	case 0x80:
555 		return " last fragment";
556 	default:
557 		return "";
558 	}
559 }
560 
csr_dump(int level,struct frame * frm)561 void csr_dump(int level, struct frame *frm)
562 {
563 	uint8_t desc, cid, type;
564 	uint16_t handle, master, addr;
565 
566 	desc = CSR_U8(frm);
567 
568 	cid = desc & 0x3f;
569 
570 	switch (cid) {
571 	case 2:
572 		bccmd_dump(level, frm);
573 		break;
574 
575 	case 20:
576 		type = CSR_U8(frm);
577 
578 		if (!p_filter(FILT_LMP)) {
579 			switch (type) {
580 			case 0x0f:
581 				frm->handle =  ((uint8_t *) frm->ptr)[17];
582 				frm->master = 0;
583 				frm->len--;
584 				lmp_dump(level, frm);
585 				return;
586 			case 0x10:
587 				frm->handle = ((uint8_t *) frm->ptr)[17];
588 				frm->master = 1;
589 				frm->len--;
590 				lmp_dump(level, frm);
591 				return;
592 			case 0x12:
593 				handle = CSR_U16(frm);
594 				master = CSR_U16(frm);
595 				addr = CSR_U16(frm);
596 				p_indent(level, frm);
597 				printf("FHS: handle %d addr %d (%s)\n", handle,
598 					addr, master ? "master" : "slave");
599 				if (!master) {
600 					char addr[18];
601 					p_ba2str((bdaddr_t *) frm->ptr, addr);
602 					p_indent(level + 1, frm);
603 					printf("bdaddr %s class "
604 						"0x%2.2x%2.2x%2.2x\n", addr,
605 						((uint8_t *) frm->ptr)[8],
606 						((uint8_t *) frm->ptr)[7],
607 						((uint8_t *) frm->ptr)[6]);
608 				}
609 				return;
610 			case 0x7b:
611 				p_indent(level, frm);
612 				printf("LMP(r): duplicate (same SEQN)\n");
613 				return;
614 			}
615 		}
616 
617 		p_indent(level, frm);
618 		printf("CSR: Debug (type 0x%2.2x)\n", type);
619 		raw_dump(level, frm);
620 		break;
621 
622 	default:
623 		p_indent(level, frm);
624 		printf("CSR: %s (channel %d)%s\n", cid2str(cid), cid, frag2str(desc));
625 		raw_dump(level, frm);
626 		break;
627 	}
628 }
629