l2cap.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
  7. * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #define _GNU_SOURCE
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <inttypes.h>
  21. #include "parser.h"
  22. #include "sdp.h"
  23. #include "l2cap.h"
  24. #include "lib/hci.h"
  25. #include "lib/a2mp.h"
  26. #include "lib/amp.h"
  27. typedef struct {
  28. uint16_t handle;
  29. struct frame frm;
  30. } handle_info;
  31. #define HANDLE_TABLE_SIZE 10
  32. static handle_info handle_table[HANDLE_TABLE_SIZE];
  33. typedef struct {
  34. uint16_t handle;
  35. uint16_t cid;
  36. uint16_t psm;
  37. uint16_t num;
  38. uint8_t mode;
  39. uint8_t ext_ctrl;
  40. } cid_info;
  41. #define CID_TABLE_SIZE 32
  42. static cid_info cid_table[2][CID_TABLE_SIZE];
  43. #define SCID cid_table[0]
  44. #define DCID cid_table[1]
  45. /* Can we move this to l2cap.h? */
  46. struct features {
  47. char *name;
  48. int flag;
  49. };
  50. static struct features l2cap_features[] = {
  51. { "Flow control mode", L2CAP_FEAT_FLOWCTL },
  52. { "Retransmission mode", L2CAP_FEAT_RETRANS },
  53. { "Bi-directional QoS", L2CAP_FEAT_BIDIR_QOS },
  54. { "Enhanced Retransmission mode", L2CAP_FEAT_ERTM },
  55. { "Streaming mode", L2CAP_FEAT_STREAMING },
  56. { "FCS Option", L2CAP_FEAT_FCS },
  57. { "Extended Flow Specification", L2CAP_FEAT_EXT_FLOW },
  58. { "Fixed Channels", L2CAP_FEAT_FIXED_CHAN },
  59. { "Extended Window Size", L2CAP_FEAT_EXT_WINDOW },
  60. { "Unicast Connectless Data Reception", L2CAP_FEAT_UCD },
  61. { 0 }
  62. };
  63. static struct features l2cap_fix_chan[] = {
  64. { "L2CAP Signalling Channel", L2CAP_FC_L2CAP },
  65. { "L2CAP Connless", L2CAP_FC_CONNLESS },
  66. { "AMP Manager Protocol", L2CAP_FC_A2MP },
  67. { 0 }
  68. };
  69. static struct frame *add_handle(uint16_t handle)
  70. {
  71. register handle_info *t = handle_table;
  72. register int i;
  73. for (i = 0; i < HANDLE_TABLE_SIZE; i++)
  74. if (!t[i].handle) {
  75. t[i].handle = handle;
  76. return &t[i].frm;
  77. }
  78. return NULL;
  79. }
  80. static struct frame *get_frame(uint16_t handle)
  81. {
  82. register handle_info *t = handle_table;
  83. register int i;
  84. for (i = 0; i < HANDLE_TABLE_SIZE; i++)
  85. if (t[i].handle == handle)
  86. return &t[i].frm;
  87. return add_handle(handle);
  88. }
  89. static void add_cid(int in, uint16_t handle, uint16_t cid, uint16_t psm)
  90. {
  91. register cid_info *table = cid_table[in];
  92. register int i, pos = -1;
  93. uint16_t num = 1;
  94. for (i = 0; i < CID_TABLE_SIZE; i++) {
  95. if ((pos < 0 && !table[i].cid) || table[i].cid == cid)
  96. pos = i;
  97. if (table[i].psm == psm)
  98. num++;
  99. }
  100. if (pos >= 0) {
  101. table[pos].handle = handle;
  102. table[pos].cid = cid;
  103. table[pos].psm = psm;
  104. table[pos].num = num;
  105. table[pos].mode = 0;
  106. }
  107. }
  108. static void del_cid(int in, uint16_t dcid, uint16_t scid)
  109. {
  110. register int t, i;
  111. uint16_t cid[2];
  112. if (!in) {
  113. cid[0] = dcid;
  114. cid[1] = scid;
  115. } else {
  116. cid[0] = scid;
  117. cid[1] = dcid;
  118. }
  119. for (t = 0; t < 2; t++) {
  120. for (i = 0; i < CID_TABLE_SIZE; i++)
  121. if (cid_table[t][i].cid == cid[t]) {
  122. cid_table[t][i].handle = 0;
  123. cid_table[t][i].cid = 0;
  124. cid_table[t][i].psm = 0;
  125. cid_table[t][i].num = 0;
  126. cid_table[t][i].mode = 0;
  127. break;
  128. }
  129. }
  130. }
  131. static void del_handle(uint16_t handle)
  132. {
  133. register int t, i;
  134. for (t = 0; t < 2; t++) {
  135. for (i = 0; i < CID_TABLE_SIZE; i++)
  136. if (cid_table[t][i].handle == handle) {
  137. cid_table[t][i].handle = 0;
  138. cid_table[t][i].cid = 0;
  139. cid_table[t][i].psm = 0;
  140. cid_table[t][i].num = 0;
  141. cid_table[t][i].mode = 0;
  142. break;
  143. }
  144. }
  145. }
  146. static uint16_t get_psm(int in, uint16_t handle, uint16_t cid)
  147. {
  148. register cid_info *table = cid_table[in];
  149. register int i;
  150. for (i = 0; i < CID_TABLE_SIZE; i++)
  151. if (table[i].handle == handle && table[i].cid == cid)
  152. return table[i].psm;
  153. return parser.defpsm;
  154. }
  155. static uint16_t get_num(int in, uint16_t handle, uint16_t cid)
  156. {
  157. register cid_info *table = cid_table[in];
  158. register int i;
  159. for (i = 0; i < CID_TABLE_SIZE; i++)
  160. if (table[i].handle == handle && table[i].cid == cid)
  161. return table[i].num;
  162. return 0;
  163. }
  164. static void set_mode(int in, uint16_t handle, uint16_t cid, uint8_t mode)
  165. {
  166. register cid_info *table = cid_table[in];
  167. register int i;
  168. for (i = 0; i < CID_TABLE_SIZE; i++)
  169. if (table[i].handle == handle && table[i].cid == cid)
  170. table[i].mode = mode;
  171. }
  172. static uint8_t get_mode(int in, uint16_t handle, uint16_t cid)
  173. {
  174. register cid_info *table = cid_table[in];
  175. register int i;
  176. for (i = 0; i < CID_TABLE_SIZE; i++)
  177. if (table[i].handle == handle && table[i].cid == cid)
  178. return table[i].mode;
  179. return 0;
  180. }
  181. static void set_ext_ctrl(int in, uint16_t handle, uint16_t cid,
  182. uint8_t ext_ctrl)
  183. {
  184. register cid_info *table = cid_table[in];
  185. register int i;
  186. for (i = 0; i < CID_TABLE_SIZE; i++)
  187. if (table[i].handle == handle && table[i].cid == cid)
  188. table[i].ext_ctrl = ext_ctrl;
  189. }
  190. static uint8_t get_ext_ctrl(int in, uint16_t handle, uint16_t cid)
  191. {
  192. register cid_info *table = cid_table[in];
  193. register int i;
  194. for (i = 0; i < CID_TABLE_SIZE; i++)
  195. if (table[i].handle == handle && table[i].cid == cid)
  196. return table[i].ext_ctrl;
  197. return 0;
  198. }
  199. static uint32_t get_val(uint8_t *ptr, uint8_t len)
  200. {
  201. switch (len) {
  202. case 1:
  203. return *ptr;
  204. case 2:
  205. return get_le16(ptr);
  206. case 4:
  207. return get_le32(ptr);
  208. }
  209. return 0;
  210. }
  211. static char *reason2str(uint16_t reason)
  212. {
  213. switch (reason) {
  214. case 0x0000:
  215. return "Command not understood";
  216. case 0x0001:
  217. return "Signalling MTU exceeded";
  218. case 0x0002:
  219. return "Invalid CID in request";
  220. default:
  221. return "Reserved";
  222. }
  223. }
  224. static char *a2mpreason2str(uint16_t reason)
  225. {
  226. switch (reason) {
  227. case A2MP_COMMAND_NOT_RECOGNIZED:
  228. return "Command not recognized";
  229. default:
  230. return "Reserved";
  231. }
  232. }
  233. static char *connresult2str(uint16_t result)
  234. {
  235. switch (result) {
  236. case 0x0000:
  237. return "Connection successful";
  238. case 0x0001:
  239. return "Connection pending";
  240. case 0x0002:
  241. return "Connection refused - PSM not supported";
  242. case 0x0003:
  243. return "Connection refused - security block";
  244. case 0x0004:
  245. return "Connection refused - no resources available";
  246. default:
  247. return "Reserved";
  248. }
  249. }
  250. static char *status2str(uint16_t status)
  251. {
  252. switch (status) {
  253. case 0x0000:
  254. return "No futher information available";
  255. case 0x0001:
  256. return "Authentication pending";
  257. case 0x0002:
  258. return "Authorization pending";
  259. default:
  260. return "Reserved";
  261. }
  262. }
  263. static char *confresult2str(uint16_t result)
  264. {
  265. switch (result) {
  266. case L2CAP_CONF_SUCCESS:
  267. return "Success";
  268. case L2CAP_CONF_UNACCEPT:
  269. return "Failure - unacceptable parameters";
  270. case L2CAP_CONF_REJECT:
  271. return "Failure - rejected (no reason provided)";
  272. case L2CAP_CONF_UNKNOWN:
  273. return "Failure - unknown options";
  274. case L2CAP_CONF_PENDING:
  275. return "Pending";
  276. case L2CAP_CONF_EFS_REJECT:
  277. return "Failure - flowspec reject";
  278. default:
  279. return "Reserved";
  280. }
  281. }
  282. static char *inforesult2str(uint16_t result)
  283. {
  284. switch (result) {
  285. case 0x0000:
  286. return "Success";
  287. case 0x0001:
  288. return "Not supported";
  289. default:
  290. return "Reserved";
  291. }
  292. }
  293. static char *type2str(uint8_t type)
  294. {
  295. switch (type) {
  296. case L2CAP_SERVTYPE_NOTRAFFIC:
  297. return "No traffic";
  298. case L2CAP_SERVTYPE_BESTEFFORT:
  299. return "Best Effort";
  300. case L2CAP_SERVTYPE_GUARANTEED:
  301. return "Guaranteed";
  302. default:
  303. return "Reserved";
  304. }
  305. }
  306. static char *mode2str(uint8_t mode)
  307. {
  308. switch (mode) {
  309. case 0x00:
  310. return "Basic";
  311. case 0x01:
  312. return "Retransmission";
  313. case 0x02:
  314. return "Flow control";
  315. case 0x03:
  316. return "Enhanced Retransmission";
  317. case 0x04:
  318. return "Streaming";
  319. default:
  320. return "Reserved";
  321. }
  322. }
  323. static char *fcs2str(uint8_t fcs)
  324. {
  325. switch (fcs) {
  326. case 0x00:
  327. return "No FCS";
  328. case 0x01:
  329. return "CRC16 Check";
  330. default:
  331. return "Reserved";
  332. }
  333. }
  334. static char *sar2str(uint8_t sar)
  335. {
  336. switch (sar) {
  337. case L2CAP_SAR_UNSEGMENTED:
  338. return "Unsegmented";
  339. case L2CAP_SAR_START:
  340. return "Start";
  341. case L2CAP_SAR_END:
  342. return "End";
  343. case L2CAP_SAR_CONTINUE:
  344. return "Continuation";
  345. default:
  346. return "Bad SAR";
  347. }
  348. }
  349. static char *supervisory2str(uint8_t supervisory)
  350. {
  351. switch (supervisory) {
  352. case L2CAP_SUPER_RR:
  353. return "Receiver Ready (RR)";
  354. case L2CAP_SUPER_REJ:
  355. return "Reject (REJ)";
  356. case L2CAP_SUPER_RNR:
  357. return "Receiver Not Ready (RNR)";
  358. case L2CAP_SUPER_SREJ:
  359. return "Select Reject (SREJ)";
  360. default:
  361. return "Bad Supervisory";
  362. }
  363. }
  364. static char *ampctrltype2str(uint8_t type)
  365. {
  366. switch (type) {
  367. case HCI_BREDR:
  368. return "BR-EDR";
  369. case HCI_AMP:
  370. return "802.11 AMP";
  371. default:
  372. return "Reserved";
  373. }
  374. }
  375. static char *ampctrlstatus2str(uint8_t status)
  376. {
  377. switch (status) {
  378. case AMP_CTRL_POWERED_DOWN:
  379. return "Powered down";
  380. case AMP_CTRL_BLUETOOTH_ONLY:
  381. return "Bluetooth only";
  382. case AMP_CTRL_NO_CAPACITY:
  383. return "No capacity";
  384. case AMP_CTRL_LOW_CAPACITY:
  385. return "Low capacity";
  386. case AMP_CTRL_MEDIUM_CAPACITY:
  387. return "Medium capacity";
  388. case AMP_CTRL_HIGH_CAPACITY:
  389. return "High capacity";
  390. case AMP_CTRL_FULL_CAPACITY:
  391. return "Full capacity";
  392. default:
  393. return "Reserved";
  394. }
  395. }
  396. static char *a2mpstatus2str(uint8_t status)
  397. {
  398. switch (status) {
  399. case A2MP_STATUS_SUCCESS:
  400. return "Success";
  401. case A2MP_STATUS_INVALID_CTRL_ID:
  402. return "Invalid Controller ID";
  403. default:
  404. return "Reserved";
  405. }
  406. }
  407. static char *a2mpcplstatus2str(uint8_t status)
  408. {
  409. switch (status) {
  410. case A2MP_STATUS_SUCCESS:
  411. return "Success";
  412. case A2MP_STATUS_INVALID_CTRL_ID:
  413. return "Invalid Controller ID";
  414. case A2MP_STATUS_UNABLE_START_LINK_CREATION:
  415. return "Failed - Unable to start link creation";
  416. case A2MP_STATUS_COLLISION_OCCURED:
  417. return "Failed - Collision occured";
  418. case A2MP_STATUS_DISCONN_REQ_RECVD:
  419. return "Failed - Disconnect physical link received";
  420. case A2MP_STATUS_PHYS_LINK_EXISTS:
  421. return "Failed - Physical link already exists";
  422. case A2MP_STATUS_SECURITY_VIOLATION:
  423. return "Failed - Security violation";
  424. default:
  425. return "Reserved";
  426. }
  427. }
  428. static char *a2mpdplstatus2str(uint8_t status)
  429. {
  430. switch (status) {
  431. case A2MP_STATUS_SUCCESS:
  432. return "Success";
  433. case A2MP_STATUS_INVALID_CTRL_ID:
  434. return "Invalid Controller ID";
  435. case A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS:
  436. return "Failed - No Physical Link exists";
  437. default:
  438. return "Reserved";
  439. }
  440. }
  441. static inline void command_rej(int level, struct frame *frm)
  442. {
  443. l2cap_cmd_rej *h = frm->ptr;
  444. uint16_t reason = btohs(h->reason);
  445. uint32_t cid;
  446. printf("Command rej: reason %d", reason);
  447. switch (reason) {
  448. case 0x0001:
  449. printf(" mtu %d\n", get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 2));
  450. break;
  451. case 0x0002:
  452. cid = get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 4);
  453. printf(" dcid 0x%4.4x scid 0x%4.4x\n", cid & 0xffff, cid >> 16);
  454. break;
  455. default:
  456. printf("\n");
  457. break;
  458. }
  459. p_indent(level + 1, frm);
  460. printf("%s\n", reason2str(reason));
  461. }
  462. static inline void conn_req(int level, struct frame *frm)
  463. {
  464. l2cap_conn_req *h = frm->ptr;
  465. uint16_t psm = btohs(h->psm);
  466. uint16_t scid = btohs(h->scid);
  467. add_cid(frm->in, frm->handle, scid, psm);
  468. if (p_filter(FILT_L2CAP))
  469. return;
  470. printf("Connect req: psm %d scid 0x%4.4x\n", psm, scid);
  471. }
  472. static inline void conn_rsp(int level, struct frame *frm)
  473. {
  474. l2cap_conn_rsp *h = frm->ptr;
  475. uint16_t scid = btohs(h->scid);
  476. uint16_t dcid = btohs(h->dcid);
  477. uint16_t result = btohs(h->result);
  478. uint16_t status = btohs(h->status);
  479. uint16_t psm;
  480. switch (h->result) {
  481. case L2CAP_CR_SUCCESS:
  482. if ((psm = get_psm(!frm->in, frm->handle, scid)))
  483. add_cid(frm->in, frm->handle, dcid, psm);
  484. break;
  485. case L2CAP_CR_PEND:
  486. break;
  487. default:
  488. del_cid(frm->in, dcid, scid);
  489. break;
  490. }
  491. if (p_filter(FILT_L2CAP))
  492. return;
  493. printf("Connect rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n",
  494. dcid, scid, result, status);
  495. p_indent(level + 1, frm);
  496. printf("%s", connresult2str(result));
  497. if (result == 0x0001)
  498. printf(" - %s\n", status2str(status));
  499. else
  500. printf("\n");
  501. }
  502. static void conf_rfc(void *ptr, int len, int in, uint16_t handle,
  503. uint16_t cid)
  504. {
  505. uint8_t mode;
  506. mode = *((uint8_t *) ptr);
  507. set_mode(!in, handle, cid, mode);
  508. printf("RFC 0x%02x (%s", mode, mode2str(mode));
  509. if (mode >= 0x01 && mode <= 0x04) {
  510. uint8_t txwin, maxtrans;
  511. uint16_t rto, mto, mps;
  512. txwin = *((uint8_t *) (ptr + 1));
  513. maxtrans = *((uint8_t *) (ptr + 2));
  514. rto = get_le16(ptr + 3);
  515. mto = get_le16(ptr + 5);
  516. mps = get_le16(ptr + 7);
  517. printf(", TxWin %d, MaxTx %d, RTo %d, MTo %d, MPS %d",
  518. txwin, maxtrans, rto, mto, mps);
  519. }
  520. printf(")");
  521. }
  522. static void conf_efs(void *ptr)
  523. {
  524. uint8_t id, ser_type;
  525. uint16_t max_sdu;
  526. uint32_t sdu_itime, access_lat, flush_to;
  527. id = get_val(ptr, sizeof(id));
  528. ser_type = get_val(ptr + 1, sizeof(ser_type));
  529. max_sdu = get_val(ptr + 2, sizeof(max_sdu));
  530. sdu_itime = get_val(ptr + 4, sizeof(sdu_itime));
  531. access_lat = get_val(ptr + 8, sizeof(access_lat));
  532. flush_to = get_val(ptr + 12, sizeof(flush_to));
  533. printf("EFS (Id 0x%02x, SerType %s, MaxSDU 0x%04x, SDUitime 0x%08x, "
  534. "AccLat 0x%08x, FlushTO 0x%08x)",
  535. id, type2str(ser_type), max_sdu, sdu_itime,
  536. access_lat, flush_to);
  537. }
  538. static void conf_fcs(void *ptr, int len)
  539. {
  540. uint8_t fcs;
  541. fcs = *((uint8_t *) ptr);
  542. printf("FCS Option");
  543. if (len > 0)
  544. printf(" 0x%2.2x (%s)", fcs, fcs2str(fcs));
  545. }
  546. static void conf_opt(int level, void *ptr, int len, int in, uint16_t handle,
  547. uint16_t cid)
  548. {
  549. int indent = 0;
  550. p_indent(level, 0);
  551. while (len > 0) {
  552. l2cap_conf_opt *h = ptr;
  553. ptr += L2CAP_CONF_OPT_SIZE + h->len;
  554. len -= L2CAP_CONF_OPT_SIZE + h->len;
  555. if (h->type & 0x80)
  556. printf("[");
  557. if (indent++) {
  558. printf("\n");
  559. p_indent(level, 0);
  560. }
  561. switch (h->type & 0x7f) {
  562. case L2CAP_CONF_MTU:
  563. set_mode(in, handle, cid, 0x00);
  564. printf("MTU");
  565. if (h->len > 0)
  566. printf(" %d", get_val(h->val, h->len));
  567. break;
  568. case L2CAP_CONF_FLUSH_TO:
  569. printf("FlushTO");
  570. if (h->len > 0)
  571. printf(" %d", get_val(h->val, h->len));
  572. break;
  573. case L2CAP_CONF_QOS:
  574. printf("QoS");
  575. if (h->len > 0)
  576. printf(" 0x%02x (%s)", *(h->val + 1), type2str(*(h->val + 1)));
  577. break;
  578. case L2CAP_CONF_RFC:
  579. conf_rfc(h->val, h->len, in, handle, cid);
  580. break;
  581. case L2CAP_CONF_FCS:
  582. conf_fcs(h->val, h->len);
  583. break;
  584. case L2CAP_CONF_EFS:
  585. conf_efs(h->val);
  586. break;
  587. case L2CAP_CONF_EWS:
  588. printf("EWS");
  589. if (h->len > 0)
  590. printf(" %d", get_val(h->val, h->len));
  591. set_ext_ctrl(in, handle, cid, 1);
  592. break;
  593. default:
  594. printf("Unknown (type %2.2x, len %d)", h->type & 0x7f, h->len);
  595. break;
  596. }
  597. if (h->type & 0x80)
  598. printf("] ");
  599. else
  600. printf(" ");
  601. }
  602. printf("\n");
  603. }
  604. static void conf_list(int level, uint8_t *list, int len)
  605. {
  606. int i;
  607. p_indent(level, 0);
  608. for (i = 0; i < len; i++) {
  609. switch (list[i] & 0x7f) {
  610. case L2CAP_CONF_MTU:
  611. printf("MTU ");
  612. break;
  613. case L2CAP_CONF_FLUSH_TO:
  614. printf("FlushTo ");
  615. break;
  616. case L2CAP_CONF_QOS:
  617. printf("QoS ");
  618. break;
  619. case L2CAP_CONF_RFC:
  620. printf("RFC ");
  621. break;
  622. case L2CAP_CONF_FCS:
  623. printf("FCS ");
  624. break;
  625. case L2CAP_CONF_EFS:
  626. printf("EFS ");
  627. break;
  628. case L2CAP_CONF_EWS:
  629. printf("EWS ");
  630. break;
  631. default:
  632. printf("%2.2x ", list[i] & 0x7f);
  633. break;
  634. }
  635. }
  636. printf("\n");
  637. }
  638. static inline void conf_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  639. {
  640. l2cap_conf_req *h = frm->ptr;
  641. uint16_t dcid = btohs(h->dcid);
  642. int clen = btohs(cmd->len) - L2CAP_CONF_REQ_SIZE;
  643. if (p_filter(FILT_L2CAP))
  644. return;
  645. printf("Config req: dcid 0x%4.4x flags 0x%2.2x clen %d\n",
  646. dcid, btohs(h->flags), clen);
  647. if (clen > 0)
  648. conf_opt(level + 1, h->data, clen, frm->in, frm->handle,
  649. dcid);
  650. }
  651. static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  652. {
  653. l2cap_conf_rsp *h = frm->ptr;
  654. uint16_t scid = btohs(h->scid);
  655. uint16_t result = btohs(h->result);
  656. int clen = btohs(cmd->len) - L2CAP_CONF_RSP_SIZE;
  657. if (p_filter(FILT_L2CAP))
  658. return;
  659. printf("Config rsp: scid 0x%4.4x flags 0x%2.2x result %d clen %d\n",
  660. scid, btohs(h->flags), result, clen);
  661. if (clen > 0) {
  662. if (result) {
  663. p_indent(level + 1, frm);
  664. printf("%s\n", confresult2str(result));
  665. }
  666. if (result == 0x0003)
  667. conf_list(level + 1, h->data, clen);
  668. else
  669. conf_opt(level + 1, h->data, clen, frm->in,
  670. frm->handle, scid);
  671. } else {
  672. p_indent(level + 1, frm);
  673. printf("%s\n", confresult2str(result));
  674. }
  675. }
  676. static inline void disconn_req(int level, struct frame *frm)
  677. {
  678. l2cap_disconn_req *h = frm->ptr;
  679. if (p_filter(FILT_L2CAP))
  680. return;
  681. printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n",
  682. btohs(h->dcid), btohs(h->scid));
  683. }
  684. static inline void disconn_rsp(int level, struct frame *frm)
  685. {
  686. l2cap_disconn_rsp *h = frm->ptr;
  687. uint16_t dcid = btohs(h->dcid);
  688. uint16_t scid = btohs(h->scid);
  689. del_cid(frm->in, dcid, scid);
  690. if (p_filter(FILT_L2CAP))
  691. return;
  692. printf("Disconn rsp: dcid 0x%4.4x scid 0x%4.4x\n",
  693. btohs(h->dcid), btohs(h->scid));
  694. }
  695. static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  696. {
  697. if (p_filter(FILT_L2CAP))
  698. return;
  699. printf("Echo req: dlen %d\n", btohs(cmd->len));
  700. raw_dump(level, frm);
  701. }
  702. static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  703. {
  704. if (p_filter(FILT_L2CAP))
  705. return;
  706. printf("Echo rsp: dlen %d\n", btohs(cmd->len));
  707. raw_dump(level, frm);
  708. }
  709. static void info_opt(int level, int type, void *ptr, int len)
  710. {
  711. uint32_t mask;
  712. uint64_t fc_mask;
  713. int i;
  714. p_indent(level, 0);
  715. switch (type) {
  716. case 0x0001:
  717. printf("Connectionless MTU %d\n", get_val(ptr, len));
  718. break;
  719. case 0x0002:
  720. mask = get_val(ptr, len);
  721. printf("Extended feature mask 0x%4.4x\n", mask);
  722. if (parser.flags & DUMP_VERBOSE)
  723. for (i=0; l2cap_features[i].name; i++)
  724. if (mask & l2cap_features[i].flag) {
  725. p_indent(level + 1, 0);
  726. printf("%s\n", l2cap_features[i].name);
  727. }
  728. break;
  729. case 0x0003:
  730. fc_mask = get_le64(ptr);
  731. printf("Fixed channel list 0x%8.8" PRIx64 "\n", fc_mask);
  732. if (parser.flags & DUMP_VERBOSE)
  733. for (i=0; l2cap_fix_chan[i].name; i++)
  734. if (fc_mask & l2cap_fix_chan[i].flag) {
  735. p_indent(level + 1, 0);
  736. printf("%s\n", l2cap_fix_chan[i].name);
  737. }
  738. break;
  739. default:
  740. printf("Unknown (len %d)\n", len);
  741. break;
  742. }
  743. }
  744. static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  745. {
  746. l2cap_info_req *h = frm->ptr;
  747. if (p_filter(FILT_L2CAP))
  748. return;
  749. printf("Info req: type %d\n", btohs(h->type));
  750. }
  751. static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  752. {
  753. l2cap_info_rsp *h = frm->ptr;
  754. uint16_t type = btohs(h->type);
  755. uint16_t result = btohs(h->result);
  756. int ilen = btohs(cmd->len) - L2CAP_INFO_RSP_SIZE;
  757. if (p_filter(FILT_L2CAP))
  758. return;
  759. printf("Info rsp: type %d result %d\n", type, result);
  760. if (ilen > 0) {
  761. info_opt(level + 1, type, h->data, ilen);
  762. } else {
  763. p_indent(level + 1, frm);
  764. printf("%s\n", inforesult2str(result));
  765. }
  766. }
  767. static void l2cap_ctrl_ext_parse(int level, struct frame *frm, uint32_t ctrl)
  768. {
  769. p_indent(level, frm);
  770. printf("%s:", ctrl & L2CAP_EXT_CTRL_FRAME_TYPE ? "S-frame" : "I-frame");
  771. if (ctrl & L2CAP_EXT_CTRL_FRAME_TYPE) {
  772. printf(" %s", supervisory2str((ctrl & L2CAP_EXT_CTRL_SUPERVISE_MASK) >>
  773. L2CAP_EXT_CTRL_SUPER_SHIFT));
  774. if (ctrl & L2CAP_EXT_CTRL_POLL)
  775. printf(" P-bit");
  776. } else {
  777. uint8_t sar = (ctrl & L2CAP_EXT_CTRL_SAR_MASK) >>
  778. L2CAP_EXT_CTRL_SAR_SHIFT;
  779. printf(" %s", sar2str(sar));
  780. if (sar == L2CAP_SAR_START) {
  781. uint16_t len;
  782. len = get_le16(frm->ptr);
  783. frm->ptr += L2CAP_SDULEN_SIZE;
  784. frm->len -= L2CAP_SDULEN_SIZE;
  785. printf(" (len %d)", len);
  786. }
  787. printf(" TxSeq %d", (ctrl & L2CAP_EXT_CTRL_TXSEQ_MASK) >>
  788. L2CAP_EXT_CTRL_TXSEQ_SHIFT);
  789. }
  790. printf(" ReqSeq %d", (ctrl & L2CAP_EXT_CTRL_REQSEQ_MASK) >>
  791. L2CAP_EXT_CTRL_REQSEQ_SHIFT);
  792. if (ctrl & L2CAP_EXT_CTRL_FINAL)
  793. printf(" F-bit");
  794. }
  795. static void l2cap_ctrl_parse(int level, struct frame *frm, uint32_t ctrl)
  796. {
  797. p_indent(level, frm);
  798. printf("%s:", ctrl & L2CAP_CTRL_FRAME_TYPE ? "S-frame" : "I-frame");
  799. if (ctrl & 0x01) {
  800. printf(" %s", supervisory2str((ctrl & L2CAP_CTRL_SUPERVISE_MASK) >>
  801. L2CAP_CTRL_SUPER_SHIFT));
  802. if (ctrl & L2CAP_CTRL_POLL)
  803. printf(" P-bit");
  804. } else {
  805. uint8_t sar = (ctrl & L2CAP_CTRL_SAR_MASK) >> L2CAP_CTRL_SAR_SHIFT;
  806. printf(" %s", sar2str(sar));
  807. if (sar == L2CAP_SAR_START) {
  808. uint16_t len;
  809. len = get_le16(frm->ptr);
  810. frm->ptr += L2CAP_SDULEN_SIZE;
  811. frm->len -= L2CAP_SDULEN_SIZE;
  812. printf(" (len %d)", len);
  813. }
  814. printf(" TxSeq %d", (ctrl & L2CAP_CTRL_TXSEQ_MASK) >> L2CAP_CTRL_TXSEQ_SHIFT);
  815. }
  816. printf(" ReqSeq %d", (ctrl & L2CAP_CTRL_REQSEQ_MASK) >> L2CAP_CTRL_REQSEQ_SHIFT);
  817. if (ctrl & L2CAP_CTRL_FINAL)
  818. printf(" F-bit");
  819. }
  820. static inline void create_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  821. {
  822. l2cap_create_req *h = frm->ptr;
  823. uint16_t psm = btohs(h->psm);
  824. uint16_t scid = btohs(h->scid);
  825. if (p_filter(FILT_L2CAP))
  826. return;
  827. printf("Create chan req: psm 0x%4.4x scid 0x%4.4x ctrl id %d\n",
  828. psm, scid, h->id);
  829. }
  830. static inline void create_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  831. {
  832. l2cap_create_rsp *h = frm->ptr;
  833. uint16_t scid = btohs(h->scid);
  834. uint16_t dcid = btohs(h->dcid);
  835. uint16_t result = btohs(h->result);
  836. uint16_t status = btohs(h->status);
  837. if (p_filter(FILT_L2CAP))
  838. return;
  839. printf("Create chan rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n",
  840. dcid, scid, result, status);
  841. }
  842. static inline void move_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  843. {
  844. l2cap_move_req *h = frm->ptr;
  845. uint16_t icid = btohs(h->icid);
  846. if (p_filter(FILT_L2CAP))
  847. return;
  848. printf("Move chan req: icid 0x%4.4x ctrl id %d\n", icid, h->id);
  849. }
  850. static inline void move_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  851. {
  852. l2cap_move_rsp *h = frm->ptr;
  853. uint16_t icid = btohs(h->icid);
  854. uint16_t result = btohs(h->result);
  855. if (p_filter(FILT_L2CAP))
  856. return;
  857. printf("Move chan rsp: icid 0x%4.4x result %d\n", icid, result);
  858. }
  859. static inline void move_cfm(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  860. {
  861. l2cap_move_cfm *h = frm->ptr;
  862. uint16_t icid = btohs(h->icid);
  863. uint16_t result = btohs(h->result);
  864. if (p_filter(FILT_L2CAP))
  865. return;
  866. printf("Move chan cfm: icid 0x%4.4x result %d\n", icid, result);
  867. }
  868. static inline void move_cfm_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
  869. {
  870. l2cap_move_cfm_rsp *h = frm->ptr;
  871. uint16_t icid = btohs(h->icid);
  872. if (p_filter(FILT_L2CAP))
  873. return;
  874. printf("Move chan cfm rsp: icid 0x%4.4x\n", icid);
  875. }
  876. static inline void a2mp_command_rej(int level, struct frame *frm)
  877. {
  878. struct a2mp_command_rej *h = frm->ptr;
  879. uint16_t reason = btohs(h->reason);
  880. printf("Command Reject: reason %d\n", reason);
  881. p_indent(level + 1, 0);
  882. printf("%s\n", a2mpreason2str(reason));
  883. }
  884. static inline void a2mp_discover_req(int level, struct frame *frm, uint16_t len)
  885. {
  886. struct a2mp_discover_req *h = frm->ptr;
  887. uint16_t mtu = btohs(h->mtu);
  888. uint8_t *octet = (uint8_t *)&(h->mask);
  889. uint16_t mask;
  890. uint8_t extension;
  891. printf("Discover req: mtu/mps %d ", mtu);
  892. len -= 2;
  893. printf("mask:");
  894. do {
  895. len -= 2;
  896. mask = get_le16(octet);
  897. printf(" 0x%4.4x", mask);
  898. extension = octet[1] & 0x80;
  899. octet += 2;
  900. } while ((extension != 0) && (len >= 2));
  901. printf("\n");
  902. }
  903. static inline void a2mp_ctrl_list_dump(int level, struct a2mp_ctrl *list, uint16_t len)
  904. {
  905. p_indent(level, 0);
  906. printf("Controller list:\n");
  907. while (len >= 3) {
  908. p_indent(level + 1, 0);
  909. printf("id %d type %d (%s) status 0x%2.2x (%s)\n",
  910. list->id, list->type, ampctrltype2str(list->type), list->status, ampctrlstatus2str(list->status));
  911. list++;
  912. len -= 3;
  913. }
  914. }
  915. static inline void a2mp_discover_rsp(int level, struct frame *frm, uint16_t len)
  916. {
  917. struct a2mp_discover_rsp *h = frm->ptr;
  918. uint16_t mtu = btohs(h->mtu);
  919. uint8_t *octet = (uint8_t *)&(h->mask);
  920. uint16_t mask;
  921. uint8_t extension;
  922. printf("Discover rsp: mtu/mps %d ", mtu);
  923. len -= 2;
  924. printf("mask:");
  925. do {
  926. len -= 2;
  927. mask = get_le16(octet);
  928. printf(" 0x%4.4x", mask);
  929. extension = octet[1] & 0x80;
  930. octet += 2;
  931. } while ((extension != 0) && (len >= 2));
  932. printf("\n");
  933. if (len >= 3) {
  934. a2mp_ctrl_list_dump(level + 1, (struct a2mp_ctrl *) octet, len);
  935. }
  936. }
  937. static inline void a2mp_change_notify(int level, struct frame *frm, uint16_t len)
  938. {
  939. struct a2mp_ctrl *list = frm->ptr;
  940. printf("Change Notify\n");
  941. if (len >= 3) {
  942. a2mp_ctrl_list_dump(level + 1, list, len);
  943. }
  944. }
  945. static inline void a2mp_change_rsp(int level, struct frame *frm)
  946. {
  947. printf("Change Response\n");
  948. }
  949. static inline void a2mp_info_req(int level, struct frame *frm)
  950. {
  951. struct a2mp_info_req *h = frm->ptr;
  952. printf("Get Info req: id %d\n", h->id);
  953. }
  954. static inline void a2mp_info_rsp(int level, struct frame *frm)
  955. {
  956. struct a2mp_info_rsp *h = frm->ptr;
  957. printf("Get Info rsp: id %d status %d (%s)\n",
  958. h->id, h->status, a2mpstatus2str(h->status));
  959. p_indent(level + 1, 0);
  960. printf("Total bandwidth %d\n", btohl(h->total_bw));
  961. p_indent(level + 1, 0);
  962. printf("Max guaranteed bandwidth %d\n", btohl(h->max_bw));
  963. p_indent(level + 1, 0);
  964. printf("Min latency %d\n", btohl(h->min_latency));
  965. p_indent(level + 1, 0);
  966. printf("Pal capabilities 0x%4.4x\n", btohs(h->pal_caps));
  967. p_indent(level + 1, 0);
  968. printf("Assoc size %d\n", btohs(h->assoc_size));
  969. }
  970. static inline void a2mp_assoc_req(int level, struct frame *frm)
  971. {
  972. struct a2mp_assoc_req *h = frm->ptr;
  973. printf("Get AMP Assoc req: id %d\n", h->id);
  974. }
  975. static inline void a2mp_assoc_rsp(int level, struct frame *frm, uint16_t len)
  976. {
  977. struct a2mp_assoc_rsp *h = frm->ptr;
  978. printf("Get AMP Assoc rsp: id %d status (%d) %s\n",
  979. h->id, h->status, a2mpstatus2str(h->status));
  980. amp_assoc_dump(level + 1, h->assoc_data, len - sizeof(*h));
  981. }
  982. static inline void a2mp_create_req(int level, struct frame *frm, uint16_t len)
  983. {
  984. struct a2mp_create_req *h = frm->ptr;
  985. printf("Create Physical Link req: local id %d remote id %d\n",
  986. h->local_id, h->remote_id);
  987. amp_assoc_dump(level + 1, h->assoc_data, len - sizeof(*h));
  988. }
  989. static inline void a2mp_create_rsp(int level, struct frame *frm)
  990. {
  991. struct a2mp_create_rsp *h = frm->ptr;
  992. printf("Create Physical Link rsp: local id %d remote id %d status %d\n",
  993. h->local_id, h->remote_id, h->status);
  994. p_indent(level+1, 0);
  995. printf("%s\n", a2mpcplstatus2str(h->status));
  996. }
  997. static inline void a2mp_disconn_req(int level, struct frame *frm)
  998. {
  999. struct a2mp_disconn_req *h = frm->ptr;
  1000. printf("Disconnect Physical Link req: local id %d remote id %d\n",
  1001. h->local_id, h->remote_id);
  1002. }
  1003. static inline void a2mp_disconn_rsp(int level, struct frame *frm)
  1004. {
  1005. struct a2mp_disconn_rsp *h = frm->ptr;
  1006. printf("Disconnect Physical Link rsp: local id %d remote id %d status %d\n",
  1007. h->local_id, h->remote_id, h->status);
  1008. p_indent(level+1, 0);
  1009. printf("%s\n", a2mpdplstatus2str(h->status));
  1010. }
  1011. static void l2cap_parse(int level, struct frame *frm)
  1012. {
  1013. l2cap_hdr *hdr = (void *)frm->ptr;
  1014. uint16_t dlen = btohs(hdr->len);
  1015. uint16_t cid = btohs(hdr->cid);
  1016. uint16_t psm;
  1017. frm->ptr += L2CAP_HDR_SIZE;
  1018. frm->len -= L2CAP_HDR_SIZE;
  1019. if (cid == 0x1) {
  1020. /* Signaling channel */
  1021. while (frm->len >= L2CAP_CMD_HDR_SIZE) {
  1022. l2cap_cmd_hdr *hdr = frm->ptr;
  1023. frm->ptr += L2CAP_CMD_HDR_SIZE;
  1024. frm->len -= L2CAP_CMD_HDR_SIZE;
  1025. if (!p_filter(FILT_L2CAP)) {
  1026. p_indent(level, frm);
  1027. printf("L2CAP(s): ");
  1028. }
  1029. switch (hdr->code) {
  1030. case L2CAP_COMMAND_REJ:
  1031. command_rej(level, frm);
  1032. break;
  1033. case L2CAP_CONN_REQ:
  1034. conn_req(level, frm);
  1035. break;
  1036. case L2CAP_CONN_RSP:
  1037. conn_rsp(level, frm);
  1038. break;
  1039. case L2CAP_CONF_REQ:
  1040. conf_req(level, hdr, frm);
  1041. break;
  1042. case L2CAP_CONF_RSP:
  1043. conf_rsp(level, hdr, frm);
  1044. break;
  1045. case L2CAP_DISCONN_REQ:
  1046. disconn_req(level, frm);
  1047. break;
  1048. case L2CAP_DISCONN_RSP:
  1049. disconn_rsp(level, frm);
  1050. break;
  1051. case L2CAP_ECHO_REQ:
  1052. echo_req(level, hdr, frm);
  1053. break;
  1054. case L2CAP_ECHO_RSP:
  1055. echo_rsp(level, hdr, frm);
  1056. break;
  1057. case L2CAP_INFO_REQ:
  1058. info_req(level, hdr, frm);
  1059. break;
  1060. case L2CAP_INFO_RSP:
  1061. info_rsp(level, hdr, frm);
  1062. break;
  1063. case L2CAP_CREATE_REQ:
  1064. create_req(level, hdr, frm);
  1065. break;
  1066. case L2CAP_CREATE_RSP:
  1067. create_rsp(level, hdr, frm);
  1068. break;
  1069. case L2CAP_MOVE_REQ:
  1070. move_req(level, hdr, frm);
  1071. break;
  1072. case L2CAP_MOVE_RSP:
  1073. move_rsp(level, hdr, frm);
  1074. break;
  1075. case L2CAP_MOVE_CFM:
  1076. move_cfm(level, hdr, frm);
  1077. break;
  1078. case L2CAP_MOVE_CFM_RSP:
  1079. move_cfm_rsp(level, hdr, frm);
  1080. break;
  1081. default:
  1082. if (p_filter(FILT_L2CAP))
  1083. break;
  1084. printf("code 0x%2.2x ident %d len %d\n",
  1085. hdr->code, hdr->ident, btohs(hdr->len));
  1086. raw_dump(level, frm);
  1087. }
  1088. if (frm->len > btohs(hdr->len)) {
  1089. frm->len -= btohs(hdr->len);
  1090. frm->ptr += btohs(hdr->len);
  1091. } else
  1092. frm->len = 0;
  1093. }
  1094. } else if (cid == 0x2) {
  1095. /* Connectionless channel */
  1096. if (p_filter(FILT_L2CAP))
  1097. return;
  1098. psm = get_le16(frm->ptr);
  1099. frm->ptr += 2;
  1100. frm->len -= 2;
  1101. p_indent(level, frm);
  1102. printf("L2CAP(c): len %d psm %d\n", dlen, psm);
  1103. raw_dump(level, frm);
  1104. } else if (cid == 0x3) {
  1105. /* AMP Manager channel */
  1106. if (p_filter(FILT_A2MP))
  1107. return;
  1108. /* Adjust for ERTM control bytes */
  1109. frm->ptr += 2;
  1110. frm->len -= 2;
  1111. while (frm->len >= A2MP_HDR_SIZE) {
  1112. struct a2mp_hdr *hdr = frm->ptr;
  1113. frm->ptr += A2MP_HDR_SIZE;
  1114. frm->len -= A2MP_HDR_SIZE;
  1115. p_indent(level, frm);
  1116. printf("A2MP: ");
  1117. switch (hdr->code) {
  1118. case A2MP_COMMAND_REJ:
  1119. a2mp_command_rej(level, frm);
  1120. break;
  1121. case A2MP_DISCOVER_REQ:
  1122. a2mp_discover_req(level, frm, btohs(hdr->len));
  1123. break;
  1124. case A2MP_DISCOVER_RSP:
  1125. a2mp_discover_rsp(level, frm, btohs(hdr->len));
  1126. break;
  1127. case A2MP_CHANGE_NOTIFY:
  1128. a2mp_change_notify(level, frm, btohs(hdr->len));
  1129. break;
  1130. case A2MP_CHANGE_RSP:
  1131. a2mp_change_rsp(level, frm);
  1132. break;
  1133. case A2MP_INFO_REQ:
  1134. a2mp_info_req(level, frm);
  1135. break;
  1136. case A2MP_INFO_RSP:
  1137. a2mp_info_rsp(level, frm);
  1138. break;
  1139. case A2MP_ASSOC_REQ:
  1140. a2mp_assoc_req(level, frm);
  1141. break;
  1142. case A2MP_ASSOC_RSP:
  1143. a2mp_assoc_rsp(level, frm, btohs(hdr->len));
  1144. break;
  1145. case A2MP_CREATE_REQ:
  1146. a2mp_create_req(level, frm, btohs(hdr->len));
  1147. break;
  1148. case A2MP_CREATE_RSP:
  1149. a2mp_create_rsp(level, frm);
  1150. break;
  1151. case A2MP_DISCONN_REQ:
  1152. a2mp_disconn_req(level, frm);
  1153. break;
  1154. case A2MP_DISCONN_RSP:
  1155. a2mp_disconn_rsp(level, frm);
  1156. break;
  1157. default:
  1158. printf("code 0x%2.2x ident %d len %d\n",
  1159. hdr->code, hdr->ident, btohs(hdr->len));
  1160. raw_dump(level, frm);
  1161. }
  1162. if (frm->len > btohs(hdr->len)) {
  1163. frm->len -= btohs(hdr->len);
  1164. frm->ptr += btohs(hdr->len);
  1165. } else
  1166. frm->len = 0;
  1167. }
  1168. } else if (cid == 0x04) {
  1169. if (!p_filter(FILT_ATT))
  1170. att_dump(level, frm);
  1171. else
  1172. raw_dump(level + 1, frm);
  1173. } else if (cid == 0x06) {
  1174. if (!p_filter(FILT_SMP))
  1175. smp_dump(level, frm);
  1176. else
  1177. raw_dump(level + 1, frm);
  1178. } else {
  1179. /* Connection oriented channel */
  1180. uint8_t mode = get_mode(!frm->in, frm->handle, cid);
  1181. uint8_t ext_ctrl = get_ext_ctrl(!frm->in, frm->handle, cid);
  1182. uint16_t psm = get_psm(!frm->in, frm->handle, cid);
  1183. uint16_t fcs = 0;
  1184. uint32_t proto, ctrl = 0;
  1185. frm->cid = cid;
  1186. frm->num = get_num(!frm->in, frm->handle, cid);
  1187. if (mode > 0) {
  1188. if (ext_ctrl) {
  1189. ctrl = get_val(frm->ptr, 4);
  1190. frm->ptr += 4;
  1191. frm->len -= 6;
  1192. } else {
  1193. ctrl = get_val(frm->ptr, 2);
  1194. frm->ptr += 2;
  1195. frm->len -= 4;
  1196. }
  1197. fcs = get_le16(frm->ptr + frm->len);
  1198. }
  1199. if (!p_filter(FILT_L2CAP)) {
  1200. p_indent(level, frm);
  1201. printf("L2CAP(d): cid 0x%4.4x len %d", cid, dlen);
  1202. if (mode > 0) {
  1203. if (ext_ctrl)
  1204. printf(" ext_ctrl 0x%8.8x fcs 0x%4.4x", ctrl, fcs);
  1205. else
  1206. printf(" ctrl 0x%4.4x fcs 0x%4.4x", ctrl, fcs);
  1207. }
  1208. printf(" [psm %d]\n", psm);
  1209. level++;
  1210. if (mode > 0) {
  1211. if (ext_ctrl)
  1212. l2cap_ctrl_ext_parse(level, frm, ctrl);
  1213. else
  1214. l2cap_ctrl_parse(level, frm, ctrl);
  1215. printf("\n");
  1216. }
  1217. }
  1218. switch (psm) {
  1219. case 0x01:
  1220. if (!p_filter(FILT_SDP))
  1221. sdp_dump(level + 1, frm);
  1222. else
  1223. raw_dump(level + 1, frm);
  1224. break;
  1225. case 0x03:
  1226. if (!p_filter(FILT_RFCOMM))
  1227. rfcomm_dump(level, frm);
  1228. else
  1229. raw_dump(level + 1, frm);
  1230. break;
  1231. case 0x0f:
  1232. if (!p_filter(FILT_BNEP))
  1233. bnep_dump(level, frm);
  1234. else
  1235. raw_dump(level + 1, frm);
  1236. break;
  1237. case 0x11:
  1238. case 0x13:
  1239. if (!p_filter(FILT_HIDP))
  1240. hidp_dump(level, frm);
  1241. else
  1242. raw_dump(level + 1, frm);
  1243. break;
  1244. case 0x17:
  1245. case 0x1B:
  1246. if (!p_filter(FILT_AVCTP))
  1247. avctp_dump(level, frm, psm);
  1248. else
  1249. raw_dump(level + 1, frm);
  1250. break;
  1251. case 0x19:
  1252. if (!p_filter(FILT_AVDTP))
  1253. avdtp_dump(level, frm);
  1254. else
  1255. raw_dump(level + 1, frm);
  1256. break;
  1257. case 0x1f:
  1258. if (!p_filter(FILT_ATT))
  1259. att_dump(level, frm);
  1260. else
  1261. raw_dump(level + 1, frm);
  1262. break;
  1263. default:
  1264. proto = get_proto(frm->handle, psm, 0);
  1265. switch (proto) {
  1266. case SDP_UUID_CMTP:
  1267. if (!p_filter(FILT_CMTP))
  1268. cmtp_dump(level, frm);
  1269. else
  1270. raw_dump(level + 1, frm);
  1271. break;
  1272. case SDP_UUID_HARDCOPY_CONTROL_CHANNEL:
  1273. if (!p_filter(FILT_HCRP))
  1274. hcrp_dump(level, frm);
  1275. else
  1276. raw_dump(level + 1, frm);
  1277. break;
  1278. case SDP_UUID_OBEX:
  1279. if (!p_filter(FILT_OBEX))
  1280. obex_dump(level, frm);
  1281. else
  1282. raw_dump(level + 1, frm);
  1283. break;
  1284. default:
  1285. if (p_filter(FILT_L2CAP))
  1286. break;
  1287. raw_dump(level, frm);
  1288. break;
  1289. }
  1290. break;
  1291. }
  1292. }
  1293. }
  1294. void l2cap_dump(int level, struct frame *frm)
  1295. {
  1296. struct frame *fr;
  1297. l2cap_hdr *hdr;
  1298. uint16_t dlen;
  1299. if ((frm->flags & ACL_START) || frm->flags == ACL_START_NO_FLUSH) {
  1300. hdr = frm->ptr;
  1301. dlen = btohs(hdr->len);
  1302. if (dlen + L2CAP_HDR_SIZE < (int) frm->len) {
  1303. /* invalid frame */
  1304. raw_dump(level,frm);
  1305. return;
  1306. }
  1307. if ((int) frm->len == (dlen + L2CAP_HDR_SIZE)) {
  1308. /* Complete frame */
  1309. l2cap_parse(level, frm);
  1310. return;
  1311. }
  1312. if (!(fr = get_frame(frm->handle))) {
  1313. fprintf(stderr, "Not enough connection handles\n");
  1314. raw_dump(level, frm);
  1315. return;
  1316. }
  1317. if (fr->data)
  1318. free(fr->data);
  1319. if (!(fr->data = malloc(dlen + L2CAP_HDR_SIZE))) {
  1320. perror("Can't allocate L2CAP reassembly buffer");
  1321. return;
  1322. }
  1323. memcpy(fr->data, frm->ptr, frm->len);
  1324. fr->data_len = dlen + L2CAP_HDR_SIZE;
  1325. fr->len = frm->len;
  1326. fr->ptr = fr->data;
  1327. fr->dev_id = frm->dev_id;
  1328. fr->in = frm->in;
  1329. fr->ts = frm->ts;
  1330. fr->handle = frm->handle;
  1331. fr->cid = frm->cid;
  1332. fr->num = frm->num;
  1333. fr->dlci = frm->dlci;
  1334. fr->channel = frm->channel;
  1335. fr->pppdump_fd = frm->pppdump_fd;
  1336. fr->audio_fd = frm->audio_fd;
  1337. } else {
  1338. if (!(fr = get_frame(frm->handle))) {
  1339. fprintf(stderr, "Not enough connection handles\n");
  1340. raw_dump(level, frm);
  1341. return;
  1342. }
  1343. if (!fr->data) {
  1344. /* Unexpected fragment */
  1345. raw_dump(level, frm);
  1346. return;
  1347. }
  1348. if (frm->len > (fr->data_len - fr->len)) {
  1349. /* Bad fragment */
  1350. raw_dump(level, frm);
  1351. free(fr->data); fr->data = NULL;
  1352. return;
  1353. }
  1354. memcpy(fr->data + fr->len, frm->ptr, frm->len);
  1355. fr->len += frm->len;
  1356. if (fr->len == fr->data_len) {
  1357. /* Complete frame */
  1358. l2cap_parse(level, fr);
  1359. free(fr->data); fr->data = NULL;
  1360. return;
  1361. }
  1362. }
  1363. }
  1364. void l2cap_clear(uint16_t handle)
  1365. {
  1366. del_handle(handle);
  1367. }