3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
37 #define CAPI_U8(frm) (get_u8(frm))
38 #define CAPI_U16(frm) (btohs(htons(get_u16(frm))))
39 #define CAPI_U32(frm) (btohl(htonl(get_u32(frm))))
41 static char *cmd2str(uint8_t cmd)
49 return "CONNECT_ACTIVE";
57 return "INTEROPERABILITY";
59 return "SELECT_B_PROTOCOL";
65 return "CONNECT_B3_ACTIVE";
67 return "DISCONNECT_B3";
73 return "CONNECT_B3_T90_ACTIVE";
75 return "MANUFACTURER";
81 static char *subcmd2str(uint8_t subcmd)
97 static char *interopsel2str(uint16_t sel)
101 return "USB Device Management";
103 return "Bluetooth Device Management";
109 static char *func2str(uint16_t func)
117 return "Get_Profile";
119 return "Get_Manufacturer";
121 return "Get_Version";
123 return "Get_Serial_Number";
125 return "Manufacturer";
127 return "Echo_Loopback";
133 static char *facilitysel2str(uint16_t sel)
143 return "Supplementary Services";
145 return "Power management wakeup";
147 return "Line Interconnect";
155 static char *info2str(uint16_t info)
161 return "NCPI not supported by current protocol, NCPI ignored";
163 return "Flags not supported by current protocol, flags ignored";
165 return "Message not supported in current state";
167 return "Incorrect Controller/PLCI/NCCI";
169 return "No PLCI available";
171 return "No NCCI available";
173 return "No Listen resources available";
175 return "Illegal message parameter coding";
177 return "No interconnection resources available";
179 return "B1 protocol not supported";
181 return "B2 protocol not supported";
183 return "B3 protocol not supported";
185 return "B1 protocol parameter not supported";
187 return "B2 protocol parameter not supported";
189 return "B3 protocol parameter not supported";
191 return "B protocol combination not supported";
193 return "NCPI not supported";
195 return "CIP Value unknown";
197 return "Flags not supported (reserved bits)";
199 return "Facility not supported";
201 return "Data length not supported by current protocol";
203 return "Reset procedure not supported by current protocol";
205 return "Unsupported interoperability";
207 return "Facility specific function not supported";
209 return "Protocol error, Layer 1";
211 return "Protocol error, Layer 2";
213 return "Protocol error, Layer 3";
215 return "Another application got that call";
217 return "Cleared by Call Control Supervision";
219 /* The cause value received from the network in a cause
220 * information element (Octet 4) is indicated in the field 00 */
221 return "Disconnect cause from the network in accordance with Q.850/ETS 300 102-1";
227 static void profile(int level, struct frame *frm)
232 nctr = CAPI_U16(frm);
233 nchn = CAPI_U16(frm);
236 p_indent(level, frm);
237 printf("Controller: %d\n", nctr);
238 p_indent(level, frm);
239 printf("Number of B-channels: %d\n", nchn);
241 value = CAPI_U32(frm);
242 p_indent(level, frm);
243 printf("Global options: 0x%04x\n", value);
244 value = CAPI_U32(frm);
245 p_indent(level, frm);
246 printf("B1 protocol support: 0x%08x\n", value);
247 value = CAPI_U32(frm);
248 p_indent(level, frm);
249 printf("B2 protocol support: 0x%08x\n", value);
250 value = CAPI_U32(frm);
251 p_indent(level, frm);
252 printf("B3 protocol support: 0x%08x\n", value);
257 p_indent(level, frm);
258 printf("Manufacturer-specific information:\n");
259 hex_dump(level, frm, 20);
261 p_indent(level, frm);
262 printf("Number of controllers: %d\n", nctr);
266 static void cmd_common(int level, uint8_t subcmd, struct frame *frm)
274 plci = (val & 0xff00) >> 8;
275 ncci = (val & 0xffff0000) >> 16;
277 p_indent(level, frm);
278 printf("Controller: %d %s\n", ctr & 0x7f, ctr & 0x80 ? "Ext." : "Int.");
281 p_indent(level, frm);
282 printf("PLCI: 0x%02x\n", plci);
286 p_indent(level, frm);
287 printf("NCCI: 0x%04x\n", ncci);
290 if (subcmd == 0x81) {
291 info = CAPI_U16(frm);
292 p_indent(level, frm);
293 printf("Info: 0x%04x (%s)\n", info, info2str(info));
297 static void cmd_alert(int level, uint8_t subcmd, struct frame *frm)
301 cmd_common(level, subcmd, frm);
303 if (subcmd == 0x80) {
306 p_indent(level, frm);
307 printf("Additional info:\n");
308 hex_dump(level, frm, len);
313 static void cmd_connect(int level, uint8_t subcmd, struct frame *frm)
318 cmd_common(level, subcmd, frm);
324 p_indent(level, frm);
325 printf("CIP value: 0x%04x\n", cip);
340 raw_dump(level, frm);
343 static void cmd_disconnect(int level, uint8_t subcmd, struct frame *frm)
348 cmd_common(level, subcmd, frm);
350 if (subcmd == 0x80) {
353 p_indent(level, frm);
354 printf("Additional info:\n");
355 hex_dump(level, frm, len);
359 if (subcmd == 0x82) {
360 reason = CAPI_U16(frm);
361 p_indent(level, frm);
362 printf("Reason: 0x%04x (%s)\n", reason, info2str(reason));
366 static void cmd_connect_active(int level, uint8_t subcmd, struct frame *frm)
370 cmd_common(level, subcmd, frm);
372 if (subcmd == 0x82) {
375 p_indent(level, frm);
376 printf("Connected number:\n");
377 hex_dump(level, frm, len);
382 p_indent(level, frm);
383 printf("Connected subaddress:\n");
384 hex_dump(level, frm, len);
389 p_indent(level, frm);
391 hex_dump(level, frm, len);
396 static void cmd_listen(int level, uint8_t subcmd, struct frame *frm)
401 cmd_common(level, subcmd, frm);
403 if (subcmd == 0x80) {
404 mask = CAPI_U32(frm);
405 p_indent(level, frm);
406 printf("Info mask: 0x%08x\n", mask);
408 mask = CAPI_U32(frm);
409 p_indent(level, frm);
410 printf("CIP mask: 0x%08x", mask);
412 mask = CAPI_U32(frm);
414 printf(" 0x%08x\n", mask);
420 p_indent(level, frm);
421 printf("Calling party number:\n");
422 hex_dump(level, frm, len);
429 p_indent(level, frm);
430 printf("Calling party subaddress:\n");
431 hex_dump(level, frm, len);
438 static void cmd_info(int level, uint8_t subcmd, struct frame *frm)
443 cmd_common(level, subcmd, frm);
449 p_indent(level, frm);
450 printf("Called party number:\n");
451 hex_dump(level, frm, len);
458 p_indent(level, frm);
459 printf("Additional info:\n");
460 hex_dump(level, frm, len);
465 info = CAPI_U16(frm);
466 p_indent(level, frm);
467 printf("Info number: %d\n", info);
471 p_indent(level, frm);
472 printf("Info element:\n");
473 hex_dump(level, frm, len);
479 static void cmd_interoperability(int level, uint8_t subcmd, struct frame *frm)
481 uint16_t sel, func, info;
482 uint16_t nconn, datablkcnt, datablklen;
483 uint32_t ctr, value, major, minor;
485 info = (subcmd == 0x81) ? CAPI_U16(frm) : 0;
488 if (subcmd != 0x83) {
489 func = CAPI_U16(frm);
494 p_indent(level, frm);
495 printf("Selector: 0x%04x (%s)\n", sel, interopsel2str(sel));
499 p_indent(level, frm);
500 printf("Function: %d (%s)\n", func, func2str(func));
506 nconn = CAPI_U16(frm);
507 p_indent(level + 1, frm);
508 printf("maxLogicalConnections: %d\n", nconn);
509 datablkcnt = CAPI_U16(frm);
510 p_indent(level + 1, frm);
511 printf("maxBDataBlocks: %d\n", datablkcnt);
512 datablklen = CAPI_U16(frm);
513 p_indent(level + 1, frm);
514 printf("maxBDataLen: %d\n", datablklen);
521 p_indent(level + 1, frm);
522 printf("Controller: %d\n", ctr);
525 raw_dump(level + 1, frm);
534 info = CAPI_U16(frm);
535 p_indent(level + 1, frm);
536 printf("Info: 0x%04x (%s)\n", info, info2str(info));
539 info = CAPI_U16(frm);
540 p_indent(level + 1, frm);
541 printf("Info: 0x%04x (%s)\n", info, info2str(info));
543 profile(level + 1, frm);
546 info = CAPI_U16(frm);
547 p_indent(level + 1, frm);
548 printf("Info: 0x%04x (%s)\n", info, info2str(info));
550 p_indent(level + 1, frm);
551 printf("Controller: %d\n", ctr);
553 p_indent(level + 1, frm);
554 printf("Identification: \"%s\"\n", (char *) frm->ptr);
557 value = CAPI_U32(frm);
558 p_indent(level + 1, frm);
559 printf("Return value: 0x%04x\n", value);
561 p_indent(level + 1, frm);
562 printf("Controller: %d\n", ctr);
563 p_indent(level + 1, frm);
564 major = CAPI_U32(frm);
565 minor = CAPI_U32(frm);
566 printf("CAPI: %d.%d\n", major, minor);
567 major = CAPI_U32(frm);
568 minor = CAPI_U32(frm);
569 p_indent(level + 1, frm);
570 printf("Manufacture: %u.%01x%01x-%02u (%d.%d)\n",
571 (major & 0xf0) >> 4, (major & 0x0f) << 4,
572 (minor & 0xf0) >> 4, minor & 0x0f,
576 value = CAPI_U32(frm);
577 p_indent(level + 1, frm);
578 printf("Return value: 0x%04x\n", value);
580 p_indent(level + 1, frm);
581 printf("Controller: %d\n", ctr);
583 p_indent(level + 1, frm);
584 printf("Serial number: %.7s\n", (char *) frm->ptr);
587 raw_dump(level + 1, frm);
593 raw_dump(level, frm);
599 p_indent(level, frm);
600 printf("Function: %d\n", func);
601 if (subcmd == 0x81) {
602 p_indent(level, frm);
603 printf("Info: 0x%04x (%s)\n", info, info2str(info));
605 raw_dump(level + 1, frm);
610 static void cmd_facility(int level, uint8_t subcmd, struct frame *frm)
614 cmd_common(level, subcmd, frm);
619 p_indent(level, frm);
620 printf("Selector: 0x%04x (%s)\n", sel, facilitysel2str(sel));
622 raw_dump(level, frm);
625 static void cmd_connect_b3(int level, uint8_t subcmd, struct frame *frm)
630 cmd_common(level, subcmd, frm);
635 if (subcmd == 0x83) {
636 reject = CAPI_U16(frm);
637 p_indent(level, frm);
638 printf("Reject: 0x%04x (%s)\n", reject, info2str(reject));
643 p_indent(level, frm);
645 hex_dump(level, frm, len);
649 static void cmd_connect_b3_active(int level, uint8_t subcmd, struct frame *frm)
653 cmd_common(level, subcmd, frm);
655 if (subcmd == 0x82) {
658 p_indent(level, frm);
660 hex_dump(level, frm, len);
665 static void cmd_disconnect_b3(int level, uint8_t subcmd, struct frame *frm)
670 cmd_common(level, subcmd, frm);
672 if (subcmd == 0x82) {
673 reason = CAPI_U16(frm);
674 p_indent(level, frm);
675 printf("Reason: 0x%04x (%s)\n", reason, info2str(reason));
678 if (subcmd == 0x80 || subcmd == 0x82) {
681 p_indent(level, frm);
683 hex_dump(level, frm, len);
688 static void cmd_data_b3(int level, uint8_t subcmd, struct frame *frm)
691 uint16_t length, handle, flags, info;
693 cmd_common(level, 0x00, frm);
695 if (subcmd == 0x81 || subcmd == 0x83) {
696 handle = CAPI_U16(frm);
697 p_indent(level, frm);
698 printf("Data handle: 0x%04x\n", handle);
700 if (subcmd == 0x81) {
701 info = CAPI_U16(frm);
702 p_indent(level, frm);
703 printf("Info: 0x%04x (%s)\n", info, info2str(info));
706 data = CAPI_U32(frm);
708 length = CAPI_U16(frm);
709 p_indent(level, frm);
710 printf("Data length: 0x%04x (%d bytes)\n", length, length);
712 handle = CAPI_U16(frm);
713 p_indent(level, frm);
714 printf("Data handle: 0x%04x\n", handle);
716 flags = CAPI_U16(frm);
717 p_indent(level, frm);
718 printf("Flags: 0x%04x\n", flags);
723 raw_dump(level, frm);
727 static void cmd_reset_b3(int level, uint8_t subcmd, struct frame *frm)
731 cmd_common(level, subcmd, frm);
733 if (subcmd == 0x80 || subcmd == 0x82) {
736 p_indent(level, frm);
738 hex_dump(level, frm, len);
743 static void cmd_manufacturer(int level, uint8_t subcmd, struct frame *frm)
745 uint32_t ctr, class, func;
750 p_indent(level, frm);
751 printf("Controller: %d\n", ctr);
753 id = (unsigned char *) frm->ptr;
754 p_indent(level, frm);
755 if (isprint(id[0]) && isprint(id[1]) && isprint(id[2]) && isprint(id[3]))
756 printf("Manufacturer: %.4s", id);
758 printf("Manufacturer: 0x%02x 0x%02x 0x%02x 0x%02x",
759 id[0], id[1], id[2], id[3]);
763 if (!strncmp((char *) id, "AVM!", 4)) {
764 class = CAPI_U32(frm);
765 func = CAPI_U32(frm);
770 printf(" [class %d func %d len %d]\n", class, func, len);
774 raw_dump(level, frm);
777 void capi_dump(int level, struct frame *frm)
779 uint16_t len, appl, msgnum;
782 len = CAPI_U16(frm) - 8;
783 appl = CAPI_U16(frm);
785 subcmd = CAPI_U8(frm);
786 msgnum = CAPI_U16(frm);
788 p_indent(level, frm);
790 printf("CAPI_%s_%s: appl %d msgnum %d len %d\n",
791 cmd2str(cmd), subcmd2str(subcmd), appl, msgnum, len);
795 cmd_alert(level + 1, subcmd, frm);
798 cmd_connect(level + 1, subcmd, frm);
801 cmd_connect_active(level + 1, subcmd, frm);
804 cmd_disconnect(level + 1, subcmd, frm);
807 cmd_listen(level + 1, subcmd, frm);
810 cmd_info(level + 1, subcmd, frm);
813 cmd_interoperability(level + 1, subcmd, frm);
816 cmd_facility(level + 1, subcmd, frm);
819 cmd_connect_b3(level + 1, subcmd, frm);
823 cmd_connect_b3_active(level + 1, subcmd, frm);
826 cmd_disconnect_b3(level + 1, subcmd, frm);
829 cmd_data_b3(level + 1, subcmd, frm);
832 cmd_reset_b3(level + 1, subcmd, frm);
835 cmd_manufacturer(level + 1, subcmd, frm);
838 raw_dump(level, frm);