rfcomm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2011-2014 Intel Corporation
  7. * Copyright (C) 2002-2010 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 <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include <inttypes.h>
  20. #include "lib/bluetooth.h"
  21. #include "lib/uuid.h"
  22. #include "src/shared/util.h"
  23. #include "bt.h"
  24. #include "packet.h"
  25. #include "display.h"
  26. #include "l2cap.h"
  27. #include "keys.h"
  28. #include "sdp.h"
  29. #include "rfcomm.h"
  30. static char *cr_str[] = {
  31. "RSP",
  32. "CMD"
  33. };
  34. /* RFCOMM frame parsing macros */
  35. #define CR_STR(type) cr_str[GET_CR(type)]
  36. #define GET_LEN8(length) ((length & 0xfe) >> 1)
  37. #define GET_LEN16(length) ((length & 0xfffe) >> 1)
  38. #define GET_CR(type) ((type & 0x02) >> 1)
  39. #define GET_PF(ctr) (((ctr) >> 4) & 0x1)
  40. /* MSC macros */
  41. #define GET_V24_FC(sigs) ((sigs & 0x02) >> 1)
  42. #define GET_V24_RTC(sigs) ((sigs & 0x04) >> 2)
  43. #define GET_V24_RTR(sigs) ((sigs & 0x08) >> 3)
  44. #define GET_V24_IC(sigs) ((sigs & 0x40) >> 6)
  45. #define GET_V24_DV(sigs) ((sigs & 0x80) >> 7)
  46. /* RPN macros */
  47. #define GET_RPN_DB(parity) (parity & 0x03)
  48. #define GET_RPN_SB(parity) ((parity & 0x04) >> 2)
  49. #define GET_RPN_PARITY(parity) ((parity & 0x08) >> 3)
  50. #define GET_RPN_PTYPE(parity) ((parity & 0x30) >> 4)
  51. #define GET_RPN_XIN(io) (io & 0x01)
  52. #define GET_RPN_XOUT(io) ((io & 0x02) >> 1)
  53. #define GET_RPN_RTRI(io) ((io & 0x04) >> 2)
  54. #define GET_RPN_RTRO(io) ((io & 0x08) >> 3)
  55. #define GET_RPN_RTCI(io) ((io & 0x10) >> 4)
  56. #define GET_RPN_RTCO(io) ((io & 0x20) >> 5)
  57. /* RLS macro */
  58. #define GET_ERROR(err) (err & 0x0f)
  59. /* PN macros */
  60. #define GET_FRM_TYPE(ctrl) ((ctrl & 0x0f))
  61. #define GET_CRT_FLOW(ctrl) ((ctrl & 0xf0) >> 4)
  62. #define GET_PRIORITY(prio) ((prio & 0x3f))
  63. #define GET_PN_DLCI(dlci) ((dlci & 0x3f))
  64. struct rfcomm_lhdr {
  65. uint8_t address;
  66. uint8_t control;
  67. uint16_t length;
  68. uint8_t fcs;
  69. uint8_t credits; /* only for UIH frame */
  70. };
  71. struct rfcomm_lmsc {
  72. uint8_t dlci;
  73. uint8_t v24_sig;
  74. uint8_t break_sig;
  75. };
  76. struct rfcomm_rpn {
  77. uint8_t dlci;
  78. uint8_t bit_rate;
  79. uint8_t parity;
  80. uint8_t io;
  81. uint8_t xon;
  82. uint8_t xoff;
  83. uint16_t pm;
  84. };
  85. struct rfcomm_rls {
  86. uint8_t dlci;
  87. uint8_t error;
  88. };
  89. struct rfcomm_nsc {
  90. uint8_t cmd_type;
  91. };
  92. struct rfcomm_lmcc {
  93. uint8_t type;
  94. uint16_t length;
  95. };
  96. struct rfcomm_frame {
  97. struct rfcomm_lhdr hdr;
  98. struct rfcomm_lmcc mcc;
  99. struct l2cap_frame l2cap_frame;
  100. };
  101. static void print_rfcomm_hdr(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  102. {
  103. struct rfcomm_lhdr hdr = rfcomm_frame->hdr;
  104. /* Address field */
  105. print_field("%*cAddress: 0x%2.2x cr %d dlci 0x%2.2x", indent, ' ',
  106. hdr.address, GET_CR(hdr.address),
  107. RFCOMM_GET_DLCI(hdr.address));
  108. /* Control field */
  109. print_field("%*cControl: 0x%2.2x poll/final %d", indent, ' ',
  110. hdr.control, GET_PF(hdr.control));
  111. /* Length and FCS */
  112. print_field("%*cLength: %d", indent, ' ', hdr.length);
  113. print_field("%*cFCS: 0x%2.2x", indent, ' ', hdr.fcs);
  114. }
  115. static inline bool mcc_test(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  116. {
  117. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  118. uint8_t data;
  119. printf("%*cTest Data: 0x ", indent, ' ');
  120. while (frame->size > 1) {
  121. if (!l2cap_frame_get_u8(frame, &data))
  122. return false;
  123. printf("%2.2x ", data);
  124. }
  125. printf("\n");
  126. return true;
  127. }
  128. static inline bool mcc_msc(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  129. {
  130. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  131. struct rfcomm_lmsc msc;
  132. if (!l2cap_frame_get_u8(frame, &msc.dlci))
  133. return false;
  134. print_field("%*cdlci %d ", indent, ' ', RFCOMM_GET_DLCI(msc.dlci));
  135. if (!l2cap_frame_get_u8(frame, &msc.v24_sig))
  136. return false;
  137. /* v24 control signals */
  138. print_field("%*cfc %d rtc %d rtr %d ic %d dv %d", indent, ' ',
  139. GET_V24_FC(msc.v24_sig), GET_V24_RTC(msc.v24_sig),
  140. GET_V24_RTR(msc.v24_sig), GET_V24_IC(msc.v24_sig),
  141. GET_V24_DV(msc.v24_sig));
  142. if (frame->size < 2)
  143. goto done;
  144. /*
  145. * TODO: Implement the break signals decoding.
  146. */
  147. packet_hexdump(frame->data, frame->size);
  148. done:
  149. return true;
  150. }
  151. static inline bool mcc_rpn(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  152. {
  153. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  154. struct rfcomm_rpn rpn;
  155. if (!l2cap_frame_get_u8(frame, &rpn.dlci))
  156. return false;
  157. print_field("%*cdlci %d", indent, ' ', RFCOMM_GET_DLCI(rpn.dlci));
  158. if (frame->size < 7)
  159. goto done;
  160. /* port value octets (optional) */
  161. if (!l2cap_frame_get_u8(frame, &rpn.bit_rate))
  162. return false;
  163. if (!l2cap_frame_get_u8(frame, &rpn.parity))
  164. return false;
  165. if (!l2cap_frame_get_u8(frame, &rpn.io))
  166. return false;
  167. print_field("%*cbr %d db %d sb %d p %d pt %d xi %d xo %d", indent, ' ',
  168. rpn.bit_rate, GET_RPN_DB(rpn.parity), GET_RPN_SB(rpn.parity),
  169. GET_RPN_PARITY(rpn.parity), GET_RPN_PTYPE(rpn.parity),
  170. GET_RPN_XIN(rpn.io), GET_RPN_XOUT(rpn.io));
  171. if (!l2cap_frame_get_u8(frame, &rpn.xon))
  172. return false;
  173. if (!l2cap_frame_get_u8(frame, &rpn.xoff))
  174. return false;
  175. print_field("%*crtri %d rtro %d rtci %d rtco %d xon %d xoff %d",
  176. indent, ' ', GET_RPN_RTRI(rpn.io), GET_RPN_RTRO(rpn.io),
  177. GET_RPN_RTCI(rpn.io), GET_RPN_RTCO(rpn.io), rpn.xon,
  178. rpn.xoff);
  179. if (!l2cap_frame_get_le16(frame, &rpn.pm))
  180. return false;
  181. print_field("%*cpm 0x%04x", indent, ' ', rpn.pm);
  182. done:
  183. return true;
  184. }
  185. static inline bool mcc_rls(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  186. {
  187. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  188. struct rfcomm_rls rls;
  189. if (!l2cap_frame_get_u8(frame, &rls.dlci))
  190. return false;
  191. if (!l2cap_frame_get_u8(frame, &rls.error))
  192. return false;
  193. print_field("%*cdlci %d error: %d", indent, ' ',
  194. RFCOMM_GET_DLCI(rls.dlci), GET_ERROR(rls.error));
  195. return true;
  196. }
  197. static inline bool mcc_pn(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  198. {
  199. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  200. struct rfcomm_pn pn;
  201. uint16_t mtu;
  202. /* rfcomm_pn struct is defined in rfcomm.h */
  203. if (!l2cap_frame_get_u8(frame, &pn.dlci))
  204. return false;
  205. if (!l2cap_frame_get_u8(frame, &pn.flow_ctrl))
  206. return false;
  207. if (!l2cap_frame_get_u8(frame, &pn.priority))
  208. return false;
  209. print_field("%*cdlci %d frame_type %d credit_flow %d pri %d", indent,
  210. ' ', GET_PN_DLCI(pn.dlci), GET_FRM_TYPE(pn.flow_ctrl),
  211. GET_CRT_FLOW(pn.flow_ctrl), GET_PRIORITY(pn.priority));
  212. if (!l2cap_frame_get_u8(frame, &pn.ack_timer))
  213. return false;
  214. if (!l2cap_frame_get_le16(frame, &mtu))
  215. return false;
  216. pn.mtu = mtu;
  217. if (!l2cap_frame_get_u8(frame, &pn.max_retrans))
  218. return false;
  219. if (!l2cap_frame_get_u8(frame, &pn.credits))
  220. return false;
  221. print_field("%*cack_timer %d frame_size %d max_retrans %d credits %d",
  222. indent, ' ', pn.ack_timer, pn.mtu, pn.max_retrans,
  223. pn.credits);
  224. return true;
  225. }
  226. static inline bool mcc_nsc(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  227. {
  228. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  229. struct rfcomm_nsc nsc;
  230. if (!l2cap_frame_get_u8(frame, &nsc.cmd_type))
  231. return false;
  232. print_field("%*ccr %d, mcc_cmd_type %x", indent, ' ',
  233. GET_CR(nsc.cmd_type), RFCOMM_GET_MCC_TYPE(nsc.cmd_type));
  234. return true;
  235. }
  236. struct mcc_data {
  237. uint8_t type;
  238. const char *str;
  239. };
  240. static const struct mcc_data mcc_table[] = {
  241. { 0x08, "Test Command" },
  242. { 0x28, "Flow Control On Command" },
  243. { 0x18, "Flow Control Off Command" },
  244. { 0x38, "Modem Status Command" },
  245. { 0x24, "Remote Port Negotiation Command" },
  246. { 0x14, "Remote Line Status" },
  247. { 0x20, "DLC Parameter Negotiation" },
  248. { 0x04, "Non Supported Command" },
  249. { }
  250. };
  251. static inline bool mcc_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  252. {
  253. uint8_t length, ex_length, type;
  254. const char *type_str;
  255. int i;
  256. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  257. struct rfcomm_lmcc mcc;
  258. const struct mcc_data *mcc_data = NULL;
  259. if (!l2cap_frame_get_u8(frame, &mcc.type) ||
  260. !l2cap_frame_get_u8(frame, &length))
  261. return false;
  262. if (RFCOMM_TEST_EA(length))
  263. mcc.length = (uint16_t) GET_LEN8(length);
  264. else {
  265. if (!l2cap_frame_get_u8(frame, &ex_length))
  266. return false;
  267. mcc.length = ((uint16_t) length << 8) | ex_length;
  268. mcc.length = GET_LEN16(mcc.length);
  269. }
  270. type = RFCOMM_GET_MCC_TYPE(mcc.type);
  271. for (i = 0; mcc_table[i].str; i++) {
  272. if (mcc_table[i].type == type) {
  273. mcc_data = &mcc_table[i];
  274. break;
  275. }
  276. }
  277. if (mcc_data)
  278. type_str = mcc_data->str;
  279. else
  280. type_str = "Unknown";
  281. print_field("%*cMCC Message type: %s %s (0x%2.2x)", indent, ' ',
  282. type_str, CR_STR(mcc.type), type);
  283. print_field("%*cLength: %d", indent+2, ' ', mcc.length);
  284. rfcomm_frame->mcc = mcc;
  285. switch (type) {
  286. case RFCOMM_TEST:
  287. return mcc_test(rfcomm_frame, indent+10);
  288. case RFCOMM_MSC:
  289. return mcc_msc(rfcomm_frame, indent+2);
  290. case RFCOMM_RPN:
  291. return mcc_rpn(rfcomm_frame, indent+2);
  292. case RFCOMM_RLS:
  293. return mcc_rls(rfcomm_frame, indent+2);
  294. case RFCOMM_PN:
  295. return mcc_pn(rfcomm_frame, indent+2);
  296. case RFCOMM_NSC:
  297. return mcc_nsc(rfcomm_frame, indent+2);
  298. default:
  299. packet_hexdump(frame->data, frame->size);
  300. }
  301. return true;
  302. }
  303. static bool uih_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent)
  304. {
  305. uint8_t credits;
  306. struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame;
  307. struct rfcomm_lhdr *hdr = &rfcomm_frame->hdr;
  308. if (!RFCOMM_GET_CHANNEL(hdr->address))
  309. return mcc_frame(rfcomm_frame, indent);
  310. /* fetching credits from UIH frame */
  311. if (GET_PF(hdr->control)) {
  312. if (!l2cap_frame_get_u8(frame, &credits))
  313. return false;
  314. hdr->credits = credits;
  315. print_field("%*cCredits: %d", indent, ' ', hdr->credits);
  316. }
  317. packet_hexdump(frame->data, frame->size);
  318. return true;
  319. }
  320. struct rfcomm_data {
  321. uint8_t frame;
  322. const char *str;
  323. };
  324. static const struct rfcomm_data rfcomm_table[] = {
  325. { 0x2f, "Set Async Balance Mode (SABM)" },
  326. { 0x63, "Unnumbered Ack (UA)" },
  327. { 0x0f, "Disconnect Mode (DM)" },
  328. { 0x43, "Disconnect (DISC)" },
  329. { 0xef, "Unnumbered Info with Header Check (UIH)" },
  330. { }
  331. };
  332. void rfcomm_packet(const struct l2cap_frame *frame)
  333. {
  334. uint8_t ctype, length, ex_length, indent = 1;
  335. const char *frame_str, *frame_color;
  336. struct l2cap_frame *l2cap_frame, tmp_frame;
  337. struct rfcomm_frame rfcomm_frame;
  338. struct rfcomm_lhdr hdr;
  339. const struct rfcomm_data *rfcomm_data = NULL;
  340. int i;
  341. l2cap_frame_pull(&rfcomm_frame.l2cap_frame, frame, 0);
  342. l2cap_frame = &rfcomm_frame.l2cap_frame;
  343. if (frame->size < 4)
  344. goto fail;
  345. if (!l2cap_frame_get_u8(l2cap_frame, &hdr.address) ||
  346. !l2cap_frame_get_u8(l2cap_frame, &hdr.control) ||
  347. !l2cap_frame_get_u8(l2cap_frame, &length))
  348. goto fail;
  349. /* length maybe 1 or 2 octets */
  350. if (RFCOMM_TEST_EA(length))
  351. hdr.length = (uint16_t) GET_LEN8(length);
  352. else {
  353. if (!l2cap_frame_get_u8(l2cap_frame, &ex_length))
  354. goto fail;
  355. hdr.length = ((uint16_t)ex_length << 8) | length;
  356. hdr.length = GET_LEN16(hdr.length);
  357. }
  358. if (!l2cap_frame->size)
  359. goto fail;
  360. l2cap_frame_pull(&tmp_frame, l2cap_frame, l2cap_frame->size-1);
  361. if (!l2cap_frame_get_u8(&tmp_frame, &hdr.fcs))
  362. goto fail;
  363. /* Decoding frame type */
  364. ctype = RFCOMM_GET_TYPE(hdr.control);
  365. for (i = 0; rfcomm_table[i].str; i++) {
  366. if (rfcomm_table[i].frame == ctype) {
  367. rfcomm_data = &rfcomm_table[i];
  368. break;
  369. }
  370. }
  371. if (rfcomm_data) {
  372. if (frame->in)
  373. frame_color = COLOR_MAGENTA;
  374. else
  375. frame_color = COLOR_BLUE;
  376. frame_str = rfcomm_data->str;
  377. } else {
  378. frame_color = COLOR_WHITE_BG;
  379. frame_str = "Unknown";
  380. }
  381. if (!rfcomm_data) {
  382. packet_hexdump(frame->data, frame->size);
  383. return;
  384. }
  385. print_indent(6, frame_color, "RFCOMM: ", frame_str, COLOR_OFF,
  386. " (0x%2.2x)", ctype);
  387. rfcomm_frame.hdr = hdr;
  388. print_rfcomm_hdr(&rfcomm_frame, indent);
  389. /* UIH frame */
  390. if (ctype == 0xef)
  391. if (!uih_frame(&rfcomm_frame, indent))
  392. goto fail;
  393. return;
  394. fail:
  395. print_text(COLOR_ERROR, "Frame too short");
  396. packet_hexdump(frame->data, frame->size);
  397. return;
  398. }