| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2004-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 <sys/socket.h>
- #include "parser.h"
- #include "lib/hci.h"
- #include "lib/hci_lib.h"
- #define LMP_U8(frm) (p_get_u8(frm))
- #define LMP_U16(frm) (btohs(htons(p_get_u16(frm))))
- #define LMP_U32(frm) (btohl(htonl(p_get_u32(frm))))
- static enum {
- IN_RAND,
- COMB_KEY_C,
- COMB_KEY_P,
- AU_RAND_C,
- AU_RAND_P,
- SRES_C,
- SRES_P,
- } pairing_state = IN_RAND;
- static struct {
- uint8_t in_rand[16];
- uint8_t comb_key_c[16];
- uint8_t comb_key_p[16];
- uint8_t au_rand_c[16];
- uint8_t au_rand_p[16];
- uint8_t sres_c[4];
- uint8_t sres_p[4];
- } pairing_data;
- static inline void pairing_data_dump(void)
- {
- int i;
- p_indent(6, NULL);
- printf("IN_RAND ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", pairing_data.in_rand[i]);
- printf("\n");
- p_indent(6, NULL);
- printf("COMB_KEY ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", pairing_data.comb_key_c[i]);
- printf(" (M)\n");
- p_indent(6, NULL);
- printf("COMB_KEY ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", pairing_data.comb_key_p[i]);
- printf(" (S)\n");
- p_indent(6, NULL);
- printf("AU_RAND ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", pairing_data.au_rand_c[i]);
- printf(" SRES ");
- for (i = 0; i < 4; i++)
- printf("%2.2x", pairing_data.sres_c[i]);
- printf(" (M)\n");
- p_indent(6, NULL);
- printf("AU_RAND ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", pairing_data.au_rand_p[i]);
- printf(" SRES ");
- for (i = 0; i < 4; i++)
- printf("%2.2x", pairing_data.sres_p[i]);
- printf(" (S)\n");
- }
- static inline void in_rand(struct frame *frm)
- {
- uint8_t *val = frm->ptr;
- memcpy(pairing_data.in_rand, val, 16);
- pairing_state = COMB_KEY_C;
- }
- static inline void comb_key(struct frame *frm)
- {
- uint8_t *val = frm->ptr;
- switch (pairing_state) {
- case COMB_KEY_C:
- memcpy(pairing_data.comb_key_c, val, 16);
- pairing_state = COMB_KEY_P;
- break;
- case COMB_KEY_P:
- memcpy(pairing_data.comb_key_p, val, 16);
- pairing_state = AU_RAND_C;
- break;
- case IN_RAND:
- case AU_RAND_C:
- case AU_RAND_P:
- case SRES_C:
- case SRES_P:
- default:
- pairing_state = IN_RAND;
- break;
- }
- }
- static inline void au_rand(struct frame *frm)
- {
- uint8_t *val = frm->ptr;
- switch (pairing_state) {
- case AU_RAND_C:
- memcpy(pairing_data.au_rand_c, val, 16);
- pairing_state = SRES_C;
- break;
- case AU_RAND_P:
- memcpy(pairing_data.au_rand_p, val, 16);
- pairing_state = SRES_P;
- break;
- case COMB_KEY_C:
- case COMB_KEY_P:
- case IN_RAND:
- case SRES_C:
- case SRES_P:
- default:
- pairing_state = IN_RAND;
- break;
- }
- }
- static inline void sres(struct frame *frm)
- {
- uint8_t *val = frm->ptr;
- switch (pairing_state) {
- case SRES_C:
- memcpy(pairing_data.sres_c, val, 4);
- pairing_state = AU_RAND_P;
- break;
- case SRES_P:
- memcpy(pairing_data.sres_p, val, 4);
- pairing_state = IN_RAND;
- pairing_data_dump();
- break;
- case COMB_KEY_C:
- case COMB_KEY_P:
- case IN_RAND:
- case AU_RAND_C:
- case AU_RAND_P:
- default:
- pairing_state = IN_RAND;
- break;
- }
- }
- static char *opcode2str(uint16_t opcode)
- {
- switch (opcode) {
- case 1:
- return "name_req";
- case 2:
- return "name_res";
- case 3:
- return "accepted";
- case 4:
- return "not_accepted";
- case 5:
- return "clkoffset_req";
- case 6:
- return "clkoffset_res";
- case 7:
- return "detach";
- case 8:
- return "in_rand";
- case 9:
- return "comb_key";
- case 10:
- return "unit_key";
- case 11:
- return "au_rand";
- case 12:
- return "sres";
- case 13:
- return "temp_rand";
- case 14:
- return "temp_key";
- case 15:
- return "encryption_mode_req";
- case 16:
- return "encryption_key_size_req";
- case 17:
- return "start_encryption_req";
- case 18:
- return "stop_encryption_req";
- case 19:
- return "switch_req";
- case 20:
- return "hold";
- case 21:
- return "hold_req";
- case 22:
- return "sniff";
- case 23:
- return "sniff_req";
- case 24:
- return "unsniff_req";
- case 25:
- return "park_req";
- case 26:
- return "park";
- case 27:
- return "set_broadcast_scan_window";
- case 28:
- return "modify_beacon";
- case 29:
- return "unpark_BD_ADDR_req";
- case 30:
- return "unpark_PM_ADDR_req";
- case 31:
- return "incr_power_req";
- case 32:
- return "decr_power_req";
- case 33:
- return "max_power";
- case 34:
- return "min_power";
- case 35:
- return "auto_rate";
- case 36:
- return "preferred_rate";
- case 37:
- return "version_req";
- case 38:
- return "version_res";
- case 39:
- return "feature_req";
- case 40:
- return "feature_res";
- case 41:
- return "quality_of_service";
- case 42:
- return "quality_of_service_req";
- case 43:
- return "SCO_link_req";
- case 44:
- return "remove_SCO_link_req";
- case 45:
- return "max_slot";
- case 46:
- return "max_slot_req";
- case 47:
- return "timing_accuracy_req";
- case 48:
- return "timing_accuracy_res";
- case 49:
- return "setup_complete";
- case 50:
- return "use_semi_permanent_key";
- case 51:
- return "host_connection_req";
- case 52:
- return "slot_offset";
- case 53:
- return "page_mode_req";
- case 54:
- return "page_scan_mode_req";
- case 55:
- return "supervision_timeout";
- case 56:
- return "test_activate";
- case 57:
- return "test_control";
- case 58:
- return "encryption_key_size_mask_req";
- case 59:
- return "encryption_key_size_mask_res";
- case 60:
- return "set_AFH";
- case 61:
- return "encapsulated_header";
- case 62:
- return "encapsulated_payload";
- case 63:
- return "simple_pairing_confirm";
- case 64:
- return "simple_pairing_number";
- case 65:
- return "DHkey_check";
- case 127 + (1 << 7):
- return "accepted_ext";
- case 127 + (2 << 7):
- return "not_accepted_ext";
- case 127 + (3 << 7):
- return "features_req_ext";
- case 127 + (4 << 7):
- return "features_res_ext";
- case 127 + (11 << 7):
- return "packet_type_table_req";
- case 127 + (12 << 7):
- return "eSCO_link_req";
- case 127 + (13 << 7):
- return "remove_eSCO_link_req";
- case 127 + (16 << 7):
- return "channel_classification_req";
- case 127 + (17 << 7):
- return "channel_classification";
- case 127 + (21 << 7):
- return "sniff_subrating_req";
- case 127 + (22 << 7):
- return "sniff_subrating_res";
- case 127 + (23 << 7):
- return "pause_encryption_req";
- case 127 + (24 << 7):
- return "resume_encryption_req";
- case 127 + (25 << 7):
- return "IO_capability_req";
- case 127 + (26 << 7):
- return "IO_capability_res";
- case 127 + (27 << 7):
- return "numeric_comparison_failed";
- case 127 + (28 << 7):
- return "passkey_failed";
- case 127 + (29 << 7):
- return "oob_failed";
- case 127 + (30 << 7):
- return "keypress_notification";
- default:
- return "unknown";
- }
- }
- static inline void name_req_dump(int level, struct frame *frm)
- {
- uint8_t offset = LMP_U8(frm);
- p_indent(level, frm);
- printf("name offset %d\n", offset);
- }
- static inline void name_res_dump(int level, struct frame *frm)
- {
- uint8_t offset = LMP_U8(frm);
- uint8_t length = LMP_U8(frm);
- uint8_t *name = frm->ptr;
- int i, size;
- frm->ptr += 14;
- frm->len -= 14;
- p_indent(level, frm);
- printf("name offset %d\n", offset);
- p_indent(level, frm);
- printf("name length %d\n", length);
- size = length - offset;
- if (size > 14)
- size = 14;
- p_indent(level, frm);
- printf("name fragment '");
- for (i = 0; i < size; i++)
- if (isprint(name[i]))
- printf("%c", name[i]);
- else
- printf(".");
- printf("'\n");
- }
- static inline void accepted_dump(int level, struct frame *frm)
- {
- uint8_t opcode = LMP_U8(frm);
- p_indent(level, frm);
- printf("op code %d (%s)\n", opcode, opcode2str(opcode));
- }
- static inline void not_accepted_dump(int level, struct frame *frm)
- {
- uint8_t opcode = LMP_U8(frm);
- uint8_t error = LMP_U8(frm);
- p_indent(level, frm);
- printf("op code %d (%s)\n", opcode, opcode2str(opcode));
- p_indent(level, frm);
- printf("error code 0x%2.2x\n", error);
- }
- static inline void clkoffset_dump(int level, struct frame *frm)
- {
- uint16_t clkoffset = LMP_U16(frm);
- p_indent(level, frm);
- printf("clock offset 0x%4.4x\n", clkoffset);
- }
- static inline void detach_dump(int level, struct frame *frm)
- {
- uint8_t error = LMP_U8(frm);
- p_indent(level, frm);
- printf("error code 0x%2.2x\n", error);
- }
- static inline void random_number_dump(int level, struct frame *frm)
- {
- uint8_t *number = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("random number ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", number[i]);
- printf("\n");
- }
- static inline void key_dump(int level, struct frame *frm)
- {
- uint8_t *key = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("key ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", key[i]);
- printf("\n");
- }
- static inline void auth_resp_dump(int level, struct frame *frm)
- {
- uint8_t *resp = frm->ptr;
- int i;
- frm->ptr += 4;
- frm->ptr -= 4;
- p_indent(level, frm);
- printf("authentication response ");
- for (i = 0; i < 4; i++)
- printf("%2.2x", resp[i]);
- printf("\n");
- }
- static inline void encryption_mode_req_dump(int level, struct frame *frm)
- {
- uint8_t mode = LMP_U8(frm);
- p_indent(level, frm);
- printf("encryption mode %d\n", mode);
- }
- static inline void encryption_key_size_req_dump(int level, struct frame *frm)
- {
- uint8_t keysize = LMP_U8(frm);
- p_indent(level, frm);
- printf("key size %d\n", keysize);
- }
- static inline void switch_req_dump(int level, struct frame *frm)
- {
- uint32_t instant = LMP_U32(frm);
- p_indent(level, frm);
- printf("switch instant 0x%4.4x\n", instant);
- }
- static inline void hold_dump(int level, struct frame *frm)
- {
- uint16_t time = LMP_U16(frm);
- uint32_t instant = LMP_U32(frm);
- p_indent(level, frm);
- printf("hold time 0x%4.4x\n", time);
- p_indent(level, frm);
- printf("hold instant 0x%4.4x\n", instant);
- }
- static inline void sniff_req_dump(int level, struct frame *frm)
- {
- uint8_t timing = LMP_U8(frm);
- uint16_t dsniff = LMP_U16(frm);
- uint16_t tsniff = LMP_U16(frm);
- uint16_t attempt = LMP_U16(frm);
- uint16_t timeout = LMP_U16(frm);
- p_indent(level, frm);
- printf("timing control flags 0x%2.2x\n", timing);
- p_indent(level, frm);
- printf("D_sniff %d T_sniff %d\n", dsniff, tsniff);
- p_indent(level, frm);
- printf("sniff attempt %d\n", attempt);
- p_indent(level, frm);
- printf("sniff timeout %d\n", timeout);
- }
- static inline void park_req_dump(int level, struct frame *frm)
- {
- uint8_t timing = LMP_U8(frm);
- uint16_t db = LMP_U16(frm);
- uint16_t tb = LMP_U16(frm);
- uint8_t nb = LMP_U8(frm);
- uint8_t xb = LMP_U8(frm);
- uint8_t pmaddr = LMP_U8(frm);
- uint8_t araddr = LMP_U8(frm);
- uint8_t nbsleep = LMP_U8(frm);
- uint8_t dbsleep = LMP_U8(frm);
- uint8_t daccess = LMP_U8(frm);
- uint8_t taccess = LMP_U8(frm);
- uint8_t nslots = LMP_U8(frm);
- uint8_t npoll = LMP_U8(frm);
- uint8_t access = LMP_U8(frm);
- p_indent(level, frm);
- printf("timing control flags 0x%2.2x\n", timing);
- p_indent(level, frm);
- printf("D_B %d T_B %d N_B %d X_B %d\n", db, tb, nb, xb);
- p_indent(level, frm);
- printf("PM_ADDR %d AR_ADDR %d\n", pmaddr, araddr);
- p_indent(level, frm);
- printf("N_Bsleep %d D_Bsleep %d\n", nbsleep, dbsleep);
- p_indent(level, frm);
- printf("D_access %d T_access %d\n", daccess, taccess);
- p_indent(level, frm);
- printf("N_acc-slots %d N_poll %d\n", nslots, npoll);
- p_indent(level, frm);
- printf("M_access %d\n", access & 0x0f);
- p_indent(level, frm);
- printf("access scheme 0x%2.2x\n", access >> 4);
- }
- static inline void modify_beacon_dump(int level, struct frame *frm)
- {
- uint8_t timing = LMP_U8(frm);
- uint16_t db = LMP_U16(frm);
- uint16_t tb = LMP_U16(frm);
- uint8_t nb = LMP_U8(frm);
- uint8_t xb = LMP_U8(frm);
- uint8_t daccess = LMP_U8(frm);
- uint8_t taccess = LMP_U8(frm);
- uint8_t nslots = LMP_U8(frm);
- uint8_t npoll = LMP_U8(frm);
- uint8_t access = LMP_U8(frm);
- p_indent(level, frm);
- printf("timing control flags 0x%2.2x\n", timing);
- p_indent(level, frm);
- printf("D_B %d T_B %d N_B %d X_B %d\n", db, tb, nb, xb);
- p_indent(level, frm);
- printf("D_access %d T_access %d\n", daccess, taccess);
- p_indent(level, frm);
- printf("N_acc-slots %d N_poll %d\n", nslots, npoll);
- p_indent(level, frm);
- printf("M_access %d\n", access & 0x0f);
- p_indent(level, frm);
- printf("access scheme 0x%2.2x\n", access >> 4);
- }
- static inline void power_req_dump(int level, struct frame *frm)
- {
- uint8_t val = LMP_U8(frm);
- p_indent(level, frm);
- printf("future use 0x%2.2x\n", val);
- }
- static inline void preferred_rate_dump(int level, struct frame *frm)
- {
- uint8_t rate = LMP_U8(frm);
- p_indent(level, frm);
- printf("data rate 0x%2.2x\n", rate);
- p_indent(level, frm);
- printf("Basic: ");
- printf("%suse FEC, ", rate & 0x01 ? "do not " : "");
- switch ((rate >> 1) & 0x03) {
- case 0x00:
- printf("no packet-size preference\n");
- break;
- case 0x01:
- printf("use 1-slot packets\n");
- break;
- case 0x02:
- printf("use 3-slot packets\n");
- break;
- case 0x03:
- printf("use 5-slot packets\n");
- break;
- }
- p_indent(level, frm);
- printf("EDR: ");
- switch ((rate >> 3) & 0x03) {
- case 0x00:
- printf("use DM1 packets, ");
- break;
- case 0x01:
- printf("use 2 Mbps packets, ");
- break;
- case 0x02:
- printf("use 3 Mbps packets, ");
- break;
- case 0x03:
- printf("reserved, \n");
- break;
- }
- switch ((rate >> 5) & 0x03) {
- case 0x00:
- printf("no packet-size preference\n");
- break;
- case 0x01:
- printf("use 1-slot packets\n");
- break;
- case 0x02:
- printf("use 3-slot packets\n");
- break;
- case 0x03:
- printf("use 5-slot packets\n");
- break;
- }
- }
- static inline void version_dump(int level, struct frame *frm)
- {
- uint8_t ver = LMP_U8(frm);
- uint16_t compid = LMP_U16(frm);
- uint16_t subver = LMP_U16(frm);
- char *tmp;
- p_indent(level, frm);
- tmp = lmp_vertostr(ver);
- printf("VersNr %d (%s)\n", ver, tmp);
- bt_free(tmp);
- p_indent(level, frm);
- printf("CompId %d (%s)\n", compid, bt_compidtostr(compid));
- p_indent(level, frm);
- printf("SubVersNr %d\n", subver);
- }
- static inline void features_dump(int level, struct frame *frm)
- {
- uint8_t *features = frm->ptr;
- int i;
- frm->ptr += 8;
- frm->len -= 8;
- p_indent(level, frm);
- printf("features");
- for (i = 0; i < 8; i++)
- printf(" 0x%2.2x", features[i]);
- printf("\n");
- }
- static inline void set_afh_dump(int level, struct frame *frm)
- {
- uint32_t instant = LMP_U32(frm);
- uint8_t mode = LMP_U8(frm);
- uint8_t *map = frm->ptr;
- int i;
- frm->ptr += 10;
- frm->len -= 10;
- p_indent(level, frm);
- printf("AFH_instant 0x%04x\n", instant);
- p_indent(level, frm);
- printf("AFH_mode %d\n", mode);
- p_indent(level, frm);
- printf("AFH_channel_map 0x");
- for (i = 0; i < 10; i++)
- printf("%2.2x", map[i]);
- printf("\n");
- }
- static inline void encapsulated_header_dump(int level, struct frame *frm)
- {
- uint8_t major = LMP_U8(frm);
- uint8_t minor = LMP_U8(frm);
- uint8_t length = LMP_U8(frm);
- p_indent(level, frm);
- printf("major type %d minor type %d payload length %d\n",
- major, minor, length);
- if (major == 1 && minor == 1) {
- p_indent(level, frm);
- printf("P-192 Public Key\n");
- }
- }
- static inline void encapsulated_payload_dump(int level, struct frame *frm)
- {
- uint8_t *value = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("data ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", value[i]);
- printf("\n");
- }
- static inline void simple_pairing_confirm_dump(int level, struct frame *frm)
- {
- uint8_t *value = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("commitment value ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", value[i]);
- printf("\n");
- }
- static inline void simple_pairing_number_dump(int level, struct frame *frm)
- {
- uint8_t *value = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("nounce value ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", value[i]);
- printf("\n");
- }
- static inline void dhkey_check_dump(int level, struct frame *frm)
- {
- uint8_t *value = frm->ptr;
- int i;
- frm->ptr += 16;
- frm->len -= 16;
- p_indent(level, frm);
- printf("confirmation value ");
- for (i = 0; i < 16; i++)
- printf("%2.2x", value[i]);
- printf("\n");
- }
- static inline void accepted_ext_dump(int level, struct frame *frm)
- {
- uint16_t opcode = LMP_U8(frm) + (LMP_U8(frm) << 7);
- p_indent(level, frm);
- printf("op code %d/%d (%s)\n", opcode & 0x7f, opcode >> 7, opcode2str(opcode));
- }
- static inline void not_accepted_ext_dump(int level, struct frame *frm)
- {
- uint16_t opcode = LMP_U8(frm) + (LMP_U8(frm) << 7);
- uint8_t error = LMP_U8(frm);
- p_indent(level, frm);
- printf("op code %d/%d (%s)\n", opcode & 0x7f, opcode >> 7, opcode2str(opcode));
- p_indent(level, frm);
- printf("error code 0x%2.2x\n", error);
- }
- static inline void features_ext_dump(int level, struct frame *frm)
- {
- uint8_t page = LMP_U8(frm);
- uint8_t max = LMP_U8(frm);
- uint8_t *features = frm->ptr;
- int i;
- frm->ptr += 8;
- frm->len -= 8;
- p_indent(level, frm);
- printf("features page %d\n", page);
- p_indent(level, frm);
- printf("max supported page %d\n", max);
- p_indent(level, frm);
- printf("extended features");
- for (i = 0; i < 8; i++)
- printf(" 0x%2.2x", features[i]);
- printf("\n");
- }
- static inline void quality_of_service_dump(int level, struct frame *frm)
- {
- uint16_t interval = LMP_U16(frm);
- uint8_t nbc = LMP_U8(frm);
- p_indent(level, frm);
- printf("poll interval %d\n", interval);
- p_indent(level, frm);
- printf("N_BC %d\n", nbc);
- }
- static inline void sco_link_req_dump(int level, struct frame *frm)
- {
- uint8_t handle = LMP_U8(frm);
- uint8_t timing = LMP_U8(frm);
- uint8_t dsco = LMP_U8(frm);
- uint8_t tsco = LMP_U8(frm);
- uint8_t packet = LMP_U8(frm);
- uint8_t airmode = LMP_U8(frm);
- p_indent(level, frm);
- printf("SCO handle %d\n", handle);
- p_indent(level, frm);
- printf("timing control flags 0x%2.2x\n", timing);
- p_indent(level, frm);
- printf("D_SCO %d T_SCO %d\n", dsco, tsco);
- p_indent(level, frm);
- printf("SCO packet 0x%2.2x\n", packet);
- p_indent(level, frm);
- printf("air mode 0x%2.2x\n", airmode);
- }
- static inline void remove_sco_link_req_dump(int level, struct frame *frm)
- {
- uint8_t handle = LMP_U8(frm);
- uint8_t error = LMP_U8(frm);
- p_indent(level, frm);
- printf("SCO handle %d\n", handle);
- p_indent(level, frm);
- printf("error code 0x%2.2x\n", error);
- }
- static inline void max_slots_dump(int level, struct frame *frm)
- {
- uint8_t slots = LMP_U8(frm);
- p_indent(level, frm);
- printf("max slots %d\n", slots);
- }
- static inline void timing_accuracy_dump(int level, struct frame *frm)
- {
- uint8_t drift = LMP_U8(frm);
- uint8_t jitter = LMP_U8(frm);
- p_indent(level, frm);
- printf("drift %d\n", drift);
- p_indent(level, frm);
- printf("jitter %d\n", jitter);
- }
- static inline void slot_offset_dump(int level, struct frame *frm)
- {
- uint16_t offset = LMP_U16(frm);
- char addr[18];
- p_ba2str((bdaddr_t *) frm->ptr, addr);
- p_indent(level, frm);
- printf("slot offset %d\n", offset);
- p_indent(level, frm);
- printf("BD_ADDR %s\n", addr);
- }
- static inline void page_mode_dump(int level, struct frame *frm)
- {
- uint8_t scheme = LMP_U8(frm);
- uint8_t settings = LMP_U8(frm);
- p_indent(level, frm);
- printf("page scheme %d\n", scheme);
- p_indent(level, frm);
- printf("page scheme settings %d\n", settings);
- }
- static inline void supervision_timeout_dump(int level, struct frame *frm)
- {
- uint16_t timeout = LMP_U16(frm);
- p_indent(level, frm);
- printf("supervision timeout %d\n", timeout);
- }
- static inline void test_control_dump(int level, struct frame *frm)
- {
- uint8_t scenario = LMP_U8(frm);
- uint8_t hopping = LMP_U8(frm);
- uint8_t txfreq = LMP_U8(frm);
- uint8_t rxfreq = LMP_U8(frm);
- uint8_t power = LMP_U8(frm);
- uint8_t poll = LMP_U8(frm);
- uint8_t packet = LMP_U8(frm);
- uint16_t length = LMP_U16(frm);
- p_indent(level, frm);
- printf("test scenario %d\n", scenario);
- p_indent(level, frm);
- printf("hopping mode %d\n", hopping);
- p_indent(level, frm);
- printf("TX frequency %d\n", txfreq);
- p_indent(level, frm);
- printf("RX frequency %d\n", rxfreq);
- p_indent(level, frm);
- printf("power control mode %d\n", power);
- p_indent(level, frm);
- printf("poll period %d\n", poll);
- p_indent(level, frm);
- printf("poll period %d\n", poll);
- p_indent(level, frm);
- printf("packet type 0x%2.2x\n", packet);
- p_indent(level, frm);
- printf("length of test data %d\n", length);
- }
- static inline void encryption_key_size_mask_res_dump(int level, struct frame *frm)
- {
- uint16_t mask = LMP_U16(frm);
- p_indent(level, frm);
- printf("key size mask 0x%4.4x\n", mask);
- }
- static inline void packet_type_table_dump(int level, struct frame *frm)
- {
- uint8_t type = LMP_U8(frm);
- p_indent(level, frm);
- printf("packet type table %d ", type);
- switch (type) {
- case 0:
- printf("(1Mbps only)\n");
- break;
- case 1:
- printf("(2/3Mbps)\n");
- break;
- default:
- printf("(Reserved)\n");
- break;
- }
- }
- static inline void esco_link_req_dump(int level, struct frame *frm)
- {
- uint8_t handle = LMP_U8(frm);
- uint8_t ltaddr = LMP_U8(frm);
- uint8_t timing = LMP_U8(frm);
- uint8_t desco = LMP_U8(frm);
- uint8_t tesco = LMP_U8(frm);
- uint8_t wesco = LMP_U8(frm);
- uint8_t cppkt = LMP_U8(frm);
- uint8_t pcpkt = LMP_U8(frm);
- uint16_t cplen = LMP_U16(frm);
- uint16_t pclen = LMP_U16(frm);
- uint8_t airmode = LMP_U8(frm);
- uint8_t negstate = LMP_U8(frm);
- p_indent(level, frm);
- printf("eSCO handle %d\n", handle);
- p_indent(level, frm);
- printf("eSCO LT_ADDR %d\n", ltaddr);
- p_indent(level, frm);
- printf("timing control flags 0x%2.2x\n", timing);
- p_indent(level, frm);
- printf("D_eSCO %d T_eSCO %d W_eSCO %d\n", desco, tesco, wesco);
- p_indent(level, frm);
- printf("eSCO C->P packet type 0x%2.2x length %d\n", cppkt, cplen);
- p_indent(level, frm);
- printf("eSCO P->C packet type 0x%2.2x length %d\n", pcpkt, pclen);
- p_indent(level, frm);
- printf("air mode 0x%2.2x\n", airmode);
- p_indent(level, frm);
- printf("negotiation state 0x%2.2x\n", negstate);
- }
- static inline void remove_esco_link_req_dump(int level, struct frame *frm)
- {
- uint8_t handle = LMP_U8(frm);
- uint8_t error = LMP_U8(frm);
- p_indent(level, frm);
- printf("eSCO handle %d\n", handle);
- p_indent(level, frm);
- printf("error code 0x%2.2x\n", error);
- }
- static inline void channel_classification_req_dump(int level, struct frame *frm)
- {
- uint8_t mode = LMP_U8(frm);
- uint16_t min = LMP_U16(frm);
- uint16_t max = LMP_U16(frm);
- p_indent(level, frm);
- printf("AFH reporting mode %d\n", mode);
- p_indent(level, frm);
- printf("AFH min interval 0x%4.4x\n", min);
- p_indent(level, frm);
- printf("AFH max interval 0x%4.4x\n", max);
- }
- static inline void channel_classification_dump(int level, struct frame *frm)
- {
- uint8_t *map = frm->ptr;
- int i;
- frm->ptr += 10;
- frm->len -= 10;
- p_indent(level, frm);
- printf("AFH channel classification 0x");
- for (i = 0; i < 10; i++)
- printf("%2.2x", map[i]);
- printf("\n");
- }
- static inline void sniff_subrating_dump(int level, struct frame *frm)
- {
- uint8_t subrate = LMP_U8(frm);
- uint16_t timeout = LMP_U16(frm);
- uint32_t instant = LMP_U32(frm);
- p_indent(level, frm);
- printf("max subrate %d\n", subrate);
- p_indent(level, frm);
- printf("min sniff timeout %d\n", timeout);
- p_indent(level, frm);
- printf("subrate instant 0x%4.4x\n", instant);
- }
- static inline void io_capability_dump(int level, struct frame *frm)
- {
- uint8_t capability = LMP_U8(frm);
- uint8_t oob_data = LMP_U8(frm);
- uint8_t authentication = LMP_U8(frm);
- p_indent(level, frm);
- printf("capability 0x%2.2x oob 0x%2.2x auth 0x%2.2x\n",
- capability, oob_data, authentication);
- }
- static inline void keypress_notification_dump(int level, struct frame *frm)
- {
- uint8_t value = LMP_U8(frm);
- p_indent(level, frm);
- printf("notification value %d\n", value);
- }
- void lmp_dump(int level, struct frame *frm)
- {
- uint8_t tmp, tid;
- uint16_t opcode;
- p_indent(level, frm);
- tmp = LMP_U8(frm);
- tid = tmp & 0x01;
- opcode = (tmp & 0xfe) >> 1;
- if (opcode > 123) {
- tmp = LMP_U8(frm);
- opcode += tmp << 7;
- }
- printf("LMP(%c): %s(%c): ", frm->central ? 's' : 'r',
- opcode2str(opcode), tid ? 'p' : 'c');
- if (opcode > 123)
- printf("op code %d/%d", opcode & 0x7f, opcode >> 7);
- else
- printf("op code %d", opcode);
- if (frm->handle > 17)
- printf(" handle %d\n", frm->handle);
- else
- printf("\n");
- if (!(parser.flags & DUMP_VERBOSE)) {
- raw_dump(level, frm);
- return;
- }
- switch (opcode) {
- case 1:
- name_req_dump(level + 1, frm);
- return;
- case 2:
- name_res_dump(level + 1, frm);
- return;
- case 3:
- accepted_dump(level + 1, frm);
- return;
- case 4:
- not_accepted_dump(level + 1, frm);
- return;
- case 6:
- clkoffset_dump(level + 1, frm);
- return;
- case 7:
- detach_dump(level + 1, frm);
- return;
- case 8:
- in_rand(frm);
- random_number_dump(level + 1, frm);
- return;
- case 9:
- comb_key(frm);
- random_number_dump(level + 1, frm);
- return;
- case 11:
- au_rand(frm);
- random_number_dump(level + 1, frm);
- return;
- case 12:
- sres(frm);
- auth_resp_dump(level + 1, frm);
- return;
- case 13:
- case 17:
- random_number_dump(level + 1, frm);
- return;
- case 10:
- case 14:
- key_dump(level + 1, frm);
- return;
- case 15:
- encryption_mode_req_dump(level + 1, frm);
- return;
- case 16:
- encryption_key_size_req_dump(level + 1, frm);
- return;
- case 19:
- switch_req_dump(level + 1, frm);
- return;
- case 20:
- case 21:
- hold_dump(level + 1, frm);
- return;
- case 23:
- sniff_req_dump(level + 1, frm);
- return;
- case 25:
- park_req_dump(level + 1, frm);
- return;
- case 28:
- modify_beacon_dump(level + 1, frm);
- return;
- case 31:
- case 32:
- power_req_dump(level + 1, frm);
- return;
- case 36:
- preferred_rate_dump(level + 1, frm);
- return;
- case 37:
- case 38:
- version_dump(level + 1, frm);
- return;
- case 39:
- case 40:
- features_dump(level + 1, frm);
- return;
- case 41:
- case 42:
- quality_of_service_dump(level + 1, frm);
- return;
- case 43:
- sco_link_req_dump(level + 1, frm);
- return;
- case 44:
- remove_sco_link_req_dump(level + 1, frm);
- return;
- case 45:
- case 46:
- max_slots_dump(level + 1, frm);
- return;
- case 48:
- timing_accuracy_dump(level + 1, frm);
- return;
- case 52:
- slot_offset_dump(level + 1, frm);
- return;
- case 53:
- case 54:
- page_mode_dump(level + 1, frm);
- return;
- case 55:
- supervision_timeout_dump(level + 1, frm);
- return;
- case 57:
- test_control_dump(level + 1, frm);
- return;
- case 59:
- encryption_key_size_mask_res_dump(level + 1, frm);
- return;
- case 60:
- set_afh_dump(level + 1, frm);
- return;
- case 61:
- encapsulated_header_dump(level + 1, frm);
- return;
- case 62:
- encapsulated_payload_dump(level + 1, frm);
- return;
- case 63:
- simple_pairing_confirm_dump(level + 1, frm);
- return;
- case 64:
- simple_pairing_number_dump(level + 1, frm);
- return;
- case 65:
- dhkey_check_dump(level + 1, frm);
- return;
- case 5:
- case 18:
- case 24:
- case 33:
- case 34:
- case 35:
- case 47:
- case 49:
- case 50:
- case 51:
- case 56:
- case 58:
- case 127 + (23 << 7):
- case 127 + (24 << 7):
- case 127 + (27 << 7):
- case 127 + (28 << 7):
- case 127 + (29 << 7):
- return;
- case 127 + (1 << 7):
- accepted_ext_dump(level + 1, frm);
- return;
- case 127 + (2 << 7):
- not_accepted_ext_dump(level + 1, frm);
- return;
- case 127 + (3 << 7):
- case 127 + (4 << 7):
- features_ext_dump(level + 1, frm);
- return;
- case 127 + (11 << 7):
- packet_type_table_dump(level + 1, frm);
- return;
- case 127 + (12 << 7):
- esco_link_req_dump(level + 1, frm);
- return;
- case 127 + (13 << 7):
- remove_esco_link_req_dump(level + 1, frm);
- return;
- case 127 + (16 << 7):
- channel_classification_req_dump(level + 1, frm);
- return;
- case 127 + (17 << 7):
- channel_classification_dump(level + 1, frm);
- return;
- case 127 + (21 << 7):
- case 127 + (22 << 7):
- sniff_subrating_dump(level + 1, frm);
- return;
- case 127 + (25 << 7):
- case 127 + (26 << 7):
- io_capability_dump(level + 1, frm);
- return;
- case 127 + (30 << 7):
- keypress_notification_dump(level + 1, frm);
- return;
- }
- raw_dump(level, frm);
- }
|